forem / forem

For empowering community 🌱
https://forem.com
GNU Affero General Public License v3.0
21.74k stars 3.97k forks source link

Duplicate entries on latest feed #9270

Open weppami opened 3 years ago

weppami commented 3 years ago

Describe the bug

Same entries are repeated in latest feed view

To Reproduce

Choose latest tab and scroll

Expected behavior No duplicates

Screenshots screencapture-dev-to-latest-1594531827631

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context

rhymes commented 3 years ago

Thanks for the issue! We'll take your request into consideration and follow up if we decide to tackle this issue.

To our amazing contributors: issues labeled type: bug are always up for grabs, but for feature requests, please wait until we add a ready for dev before starting to work on it.

To claim an issue to work on, please leave a comment. If you've claimed the issue and need help, please ping @thepracticaldev/oss and we will follow up within 3 business days.

For full info on how to contribute, please check out our contributors guide.

rhymes commented 3 years ago

I experienced the same, not sure what happened

Screenshot_2020-07-08 DEV Community 👩‍💻👨‍💻

Rafi993 commented 3 years ago

Hi there, If this bug is not taken I would like to help

rhymes commented 3 years ago

@Rafi993 go ahead!

Rafi993 commented 3 years ago

Thank you @rhymes

Rafi993 commented 3 years ago

Hi there, I have been caught up in other things lately. I'll just remove my self as assignee from this issue and comeback later if this issue is still there. Thank you @rhymes

Rafi993 commented 3 years ago

Hello there, I'll take up this issue again if it is not solved yet.

Rafi993 commented 3 years ago

Thanks @rhymes

Rafi993 commented 3 years ago

I tried to reproduce this issue in local I could not. I tried with sees size 3 It is still not there. I am going to check the actual dev.to site to see if this issue still there and if it is issue in lazyloading or this issue in the data that reaches the front end.

Rafi993 commented 3 years ago

My guess this is some issue in insertArticles function in app/assets/javascripts/initializers/initScrolling.js. I'll try to verify this.

Rafi993 commented 3 years ago

I was wrong it issue in the data of the feed itself

When I hit url https://dev.to/search/feed_content?per_page=15&page=1&sort_by=hotness_score&sort_direction=desc&approved=&class_name=Article I get

Click to see the full JSON response ```json { "result": [ { "reading_time": 4, "main_image": "https://res.cloudinary.com/practicaldev/image/fetch/s--YkBp5rvw--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/aeb778h5oqdwj6a74iee.png", "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Implement a simple chat queue in JavaScript ", "video_duration_string": "0:00", "tags": [ { "name": "twitch", "keywords_for_search": null }, { "name": "javascript", "keywords_for_search": "js" }, { "name": "tutorial", "keywords_for_search": null }, { "name": "bot", "keywords_for_search": null } ], "path": "/bdougieyo/implement-a-simple-chat-queue-in-a-javascript-5cbl", "comments_count": 4, "public_reactions_count": 21, "id": 424116, "published_at": "2020-08-11T01:16:34.330Z", "class_name": "Article", "user": { "name": "Brian Douglas", "id": 19970, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--WVPLeWOi--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/19970/6dc0f11e-a4da-4762-aed8-11f70143d31b.jpeg", "username": "bdougieyo" }, "tag_list": ["twitch", "javascript", "tutorial", "bot"], "flare_tag": null, "user_id": 19970, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": "https://res.cloudinary.com/practicaldev/image/fetch/s--YkBp5rvw--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/aeb778h5oqdwj6a74iee.png", "title": "Implement a simple chat queue in JavaScript " }, "_score": null, "published_at_int": 1597108594, "published_timestamp": "2020-08-11T01:16:34.330Z" }, { "reading_time": 5, "main_image": "https://res.cloudinary.com/practicaldev/image/fetch/s--iKx2DxZs--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/krzx151whnioxrk6u4n5.jpg", "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Directions and roadmaps", "video_duration_string": "0:00", "tags": [ { "name": "devjournal", "keywords_for_search": null }, { "name": "planning", "keywords_for_search": null }, { "name": "architecture", "keywords_for_search": null } ], "path": "/darklang/directions-and-roadmaps-3p64", "comments_count": 0, "public_reactions_count": 0, "organization": { "name": "Darklang", "id": 1018, "slug": "darklang", "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--bslsi2bw--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/organization/profile_image/1018/8c060fcc-4e03-4760-b1e7-cb6437ac2e5e.png" }, "id": 424285, "published_at": "2020-08-11T17:28:40.572Z", "class_name": "Article", "user": { "name": "Paul Biggar", "id": 207415, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--WLnkb424--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/207415/9fb39997-ad13-48c7-8905-1522613d40f3.jpg", "username": "paulbiggar" }, "tag_list": ["devjournal", "planning", "architecture"], "flare_tag": null, "user_id": 207415, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": "https://res.cloudinary.com/practicaldev/image/fetch/s--iKx2DxZs--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/krzx151whnioxrk6u4n5.jpg", "title": "Directions and roadmaps" }, "_score": null, "published_at_int": 1597166920, "published_timestamp": "2020-08-11T17:28:40.572Z" }, { "reading_time": 1, "main_image": "https://dev-to-uploads.s3.amazonaws.com/i/uw1nkt5lk6pcyscwk0jk.jpg", "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Announcing the npm@7 beta!", "video_duration_string": "0:00", "tags": [ { "name": "npm", "keywords_for_search": null }, { "name": "node", "keywords_for_search": "" }, { "name": "javascript", "keywords_for_search": "js" }, { "name": "cli", "keywords_for_search": null } ], "path": "/ruyadorno/announcing-the-npm-7-beta-34", "comments_count": 0, "public_reactions_count": 3, "id": 417422, "published_at": "2020-08-11T17:19:44.343Z", "class_name": "Article", "user": { "name": "Ruy Adorno", "id": 66669, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--oZTwOYnv--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/66669/dae5fd89-191a-45fc-b640-39f9c78029e6.jpg", "username": "ruyadorno" }, "tag_list": ["npm", "node", "javascript", "cli"], "flare_tag": null, "user_id": 66669, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": "https://dev-to-uploads.s3.amazonaws.com/i/uw1nkt5lk6pcyscwk0jk.jpg", "title": "Announcing the npm@7 beta!" }, "_score": null, "published_at_int": 1597166384, "published_timestamp": "2020-08-11T17:19:44.343Z" }, { "reading_time": 4, "main_image": "https://cdn.sanity.io/images/rx426fbd/production/5c275412cc017bfdb72911fd234eb1fcf3cd0f54-1920x1080.png?w=1400\u0026h=788\u0026fit=crop\u0026fm=webp", "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "I Created My First Google Chrome Extension", "video_duration_string": "0:00", "tags": [ { "name": "javascript", "keywords_for_search": "js" }, { "name": "webdev", "keywords_for_search": "web development" }, { "name": "productivity", "keywords_for_search": "" } ], "path": "/jamesqquick/i-created-my-first-google-chrome-extension-645", "comments_count": 0, "public_reactions_count": 3, "id": 424778, "published_at": "2020-08-11T13:00:19.000Z", "class_name": "Article", "user": { "name": "James Q Quick", "id": 53395, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--3e_kYU0R--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/53395/bee18cf6-d0e2-4818-b00c-a018b4f994f0.jpg", "username": "jamesqquick" }, "tag_list": ["javascript", "webdev", "productivity"], "flare_tag": null, "user_id": 53395, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": "https://cdn.sanity.io/images/rx426fbd/production/5c275412cc017bfdb72911fd234eb1fcf3cd0f54-1920x1080.png?w=1400\u0026h=788\u0026fit=crop\u0026fm=webp", "title": "I Created My First Google Chrome Extension" }, "_score": null, "published_at_int": 1597150819, "published_timestamp": "2020-08-11T13:00:19.000Z" }, { "reading_time": 2, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "3 Efficient ways to get tomorrow date using javascript", "video_duration_string": "0:00", "tags": [ { "name": "node", "keywords_for_search": "" }, { "name": "javascript", "keywords_for_search": "js" }, { "name": "webdev", "keywords_for_search": "web development" }, { "name": "showdev", "keywords_for_search": "" } ], "path": "/ganeshmani/3-efficient-ways-to-get-tomorrow-date-using-javascript-10b1", "comments_count": 0, "public_reactions_count": 2, "flare_tag_hash": { "text_color_hex": "#b2ffe1", "name": "showdev", "bg_color_hex": "#091b47" }, "id": 424860, "published_at": "2020-08-11T17:06:07.768Z", "class_name": "Article", "user": { "name": "GaneshMani", "id": 74349, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--y87Rsp4t--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/74349/5ae78f50-6fa3-41dc-98f9-af2ecda7d1c3.jpeg", "username": "ganeshmani" }, "tag_list": ["node", "javascript", "webdev", "showdev"], "flare_tag": { "text_color_hex": "#b2ffe1", "name": "showdev", "bg_color_hex": "#091b47" }, "user_id": 74349, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "3 Efficient ways to get tomorrow date using javascript" }, "_score": null, "published_at_int": 1597165567, "published_timestamp": "2020-08-11T17:06:07.768Z" }, { "reading_time": 3, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "React: Criando Hooks Customizados", "video_duration_string": "0:00", "tags": [], "path": "/joaomarcusc/react-criando-hooks-customizados-1l8l", "comments_count": 0, "public_reactions_count": 0, "id": 424856, "published_at": "2020-08-11T17:09:19.635Z", "class_name": "Article", "user": { "name": "João", "id": 25110, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s---fX5XN6l--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/25110/c45c26af-16df-446d-93a1-b7c5ea331cc7.png", "username": "joaomarcusc" }, "tag_list": [], "flare_tag": null, "user_id": 25110, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "React: Criando Hooks Customizados" }, "_score": null, "published_at_int": 1597165759, "published_timestamp": "2020-08-11T17:09:19.635Z" }, { "reading_time": 2, "main_image": "https://res.cloudinary.com/practicaldev/image/fetch/s--zv88jUxL--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/8tpd5g25j3mbw1lj7dpc.png", "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "🔥 Rest Assured API Testing Tutorial | Serialization and Deserialization in RestAssured | Day 17", "video_duration_string": "0:00", "tags": [ { "name": "testing", "keywords_for_search": null }, { "name": "tutorial", "keywords_for_search": null }, { "name": "webdev", "keywords_for_search": "web development" }, { "name": "beginners", "keywords_for_search": "" } ], "path": "/promode/rest-assured-api-testing-tutorial-serialization-and-deserialization-in-restassured-day-17-680", "comments_count": 0, "public_reactions_count": 4, "id": 424845, "published_at": "2020-08-11T16:43:41.832Z", "class_name": "Article", "user": { "name": "Pramod Dutta", "id": 286811, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--yNPklYjB--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/286811/54d3506c-8230-451b-b76d-3fd4b8fce165.png", "username": "promode" }, "tag_list": ["testing", "tutorial", "webdev", "beginners"], "flare_tag": null, "user_id": 286811, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": "https://res.cloudinary.com/practicaldev/image/fetch/s--zv88jUxL--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/8tpd5g25j3mbw1lj7dpc.png", "title": "🔥 Rest Assured API Testing Tutorial | Serialization and Deserialization in RestAssured | Day 17" }, "_score": null, "published_at_int": 1597164221, "published_timestamp": "2020-08-11T16:43:41.832Z" }, { "reading_time": 9, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "How to Find the Right Fintech App Development Company?", "video_duration_string": "0:00", "tags": [ { "name": "webdev", "keywords_for_search": "web development" }, { "name": "startup", "keywords_for_search": null }, { "name": "fintech", "keywords_for_search": null }, { "name": "development", "keywords_for_search": null } ], "path": "/techticsolutions/how-to-find-the-right-fintech-app-development-company-2b5o", "comments_count": 0, "public_reactions_count": 1, "id": 424827, "published_at": "2020-08-11T16:29:44.155Z", "class_name": "Article", "user": { "name": "Techtic Solutions Inc", "id": 132452, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--y98XGRV6--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/132452/35606225-389c-4924-8ce0-789acc76f989.png", "username": "techticsolutions" }, "tag_list": ["webdev", "startup", "fintech", "development"], "flare_tag": null, "user_id": 132452, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "How to Find the Right Fintech App Development Company?" }, "_score": null, "published_at_int": 1597163384, "published_timestamp": "2020-08-11T16:29:44.155Z" }, { "reading_time": 2, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Introducing para: A package metrics tool", "video_duration_string": "0:00", "tags": [ { "name": "snap", "keywords_for_search": null }, { "name": "brew", "keywords_for_search": null }, { "name": "github", "keywords_for_search": null }, { "name": "opensource", "keywords_for_search": "" } ], "path": "/felicianotech/introducing-para-a-package-metrics-tool-pkd", "comments_count": 0, "public_reactions_count": 1, "id": 424822, "published_at": "2020-08-11T16:00:00.000Z", "class_name": "Article", "user": { "name": "Ricardo N Feliciano", "id": 105644, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--2dzlCSfX--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/105644/30d38d2d-f95e-4316-a093-8847f6e2ba1a.jpg", "username": "felicianotech" }, "tag_list": ["snap", "brew", "github", "opensource"], "flare_tag": null, "user_id": 105644, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "Introducing para: A package metrics tool" }, "_score": null, "published_at_int": 1597161600, "published_timestamp": "2020-08-11T16:00:00.000Z" }, { "reading_time": 1, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Sidecar pattern and Ursc", "video_duration_string": "0:00", "tags": [ { "name": "sidecar", "keywords_for_search": null }, { "name": "ursc", "keywords_for_search": null }, { "name": "pattern", "keywords_for_search": null } ], "path": "/hyenast2/sidecar-pattern-and-ursc-3pmg", "comments_count": 0, "public_reactions_count": 0, "id": 424877, "published_at": "2020-08-11T17:39:41.180Z", "class_name": "Article", "user": { "name": "Hyena", "id": 5002, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--tBOxO8rg--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/5002/53aac333-b5cb-4de0-9bb4-d18e74f0ea85.jpg", "username": "hyenast2" }, "tag_list": ["sidecar", "ursc", "pattern"], "flare_tag": null, "user_id": 5002, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "Sidecar pattern and Ursc" }, "_score": null, "published_at_int": 1597167581, "published_timestamp": "2020-08-11T17:39:41.180Z" }, { "reading_time": 1, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "The Maintainers: Shaun Walker and DotNetNuke", "video_duration_string": "0:00", "tags": [ { "name": "video", "keywords_for_search": null }, { "name": "opensource", "keywords_for_search": "" } ], "path": "/shawnwildermuth/the-maintainers-shaun-walker-and-dotnetnuke-2k6p", "comments_count": 0, "public_reactions_count": 0, "id": 423224, "published_at": "2020-08-09T23:33:37.000Z", "class_name": "Article", "user": { "name": "Shawn Wildermuth", "id": 63451, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--pzfCeP-B--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/63451/ad7c3309-58e9-4a89-b82c-ab552d68a0ad.jpg", "username": "shawnwildermuth" }, "tag_list": ["video", "opensource"], "flare_tag": null, "user_id": 63451, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "The Maintainers: Shaun Walker and DotNetNuke" }, "_score": null, "published_at_int": 1597016017, "published_timestamp": "2020-08-09T23:33:37.000Z" }, { "reading_time": 9, "main_image": "https://dev-to-uploads.s3.amazonaws.com/i/tpsl1t2gxly3qs24efql.png", "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Richer, more accessible UIs with React Spectrum", "video_duration_string": "0:00", "tags": [ { "name": "react", "keywords_for_search": "" }, { "name": "ui", "keywords_for_search": null }, { "name": "a11y", "keywords_for_search": "accessibility disabilities" } ], "path": "/logrocket/richer-more-accessible-uis-with-react-spectrum-1oc1", "comments_count": 0, "public_reactions_count": 1, "organization": { "name": "LogRocket", "id": 1506, "slug": "logrocket", "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--tQEgvw8k--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/organization/profile_image/1506/e0a84c58-6a79-4f06-9149-87a38b84afa8.png" }, "id": 424679, "published_at": "2020-08-11T13:00:14.000Z", "class_name": "Article", "user": { "name": "Brian Neville-O'Neill", "id": 51699, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--1RFivLam--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/51699/bb86cccb-2a64-48a2-b1bb-fb9bc58e885a.jpg", "username": "bnevilleoneill" }, "tag_list": ["react", "ui", "a11y"], "flare_tag": null, "user_id": 51699, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": "https://dev-to-uploads.s3.amazonaws.com/i/tpsl1t2gxly3qs24efql.png", "title": "Richer, more accessible UIs with React Spectrum" }, "_score": null, "published_at_int": 1597150814, "published_timestamp": "2020-08-11T13:00:14.000Z" }, { "reading_time": 2, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "How to enable automatic runtime in React 17 with @babel/preset-react?", "video_duration_string": "0:00", "tags": [ { "name": "react", "keywords_for_search": "" }, { "name": "babel", "keywords_for_search": "" }, { "name": "javascript", "keywords_for_search": "js" }, { "name": "tutorial", "keywords_for_search": null } ], "path": "/wojtekmaj/how-to-enable-automatic-runtime-in-react-17-with-babel-preset-react-52l", "comments_count": 0, "public_reactions_count": 2, "id": 424757, "published_at": "2020-08-11T15:07:32.577Z", "class_name": "Article", "user": { "name": "Wojciech Maj", "id": 13177, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--4JHdxkY0--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/13177/d3d82639-5888-47bf-89f0-3e8eb2ddc9b9.jpg", "username": "wojtekmaj" }, "tag_list": ["react", "babel", "javascript", "tutorial"], "flare_tag": null, "user_id": 13177, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "How to enable automatic runtime in React 17 with @babel/preset-react?" }, "_score": null, "published_at_int": 1597158452, "published_timestamp": "2020-08-11T15:07:32.577Z" }, { "reading_time": 1, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "TC39er.us with Allen Wirfs-Brock!", "video_duration_string": "0:00", "tags": [ { "name": "javascript", "keywords_for_search": "js" }, { "name": "podcast", "keywords_for_search": "" } ], "path": "/hemanth/tc39er-us-with-allen-wirfs-brock-1oci", "comments_count": 0, "public_reactions_count": 1, "id": 424714, "published_at": "2020-08-11T14:05:00.541Z", "class_name": "Article", "user": { "name": "hemanth.hm", "id": 697, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--kuu-illS--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/697/18315.jpeg", "username": "hemanth" }, "tag_list": ["javascript", "podcast"], "flare_tag": null, "user_id": 697, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "TC39er.us with Allen Wirfs-Brock!" }, "_score": null, "published_at_int": 1597154700, "published_timestamp": "2020-08-11T14:05:00.541Z" }, { "reading_time": 5, "main_image": "https://res.cloudinary.com/practicaldev/image/fetch/s--lTmZnHcv--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/ieucrtuqfgmjiar7q8o5.png", "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Best Resources To Learn JavaScript As A Beginner", "video_duration_string": "0:00", "tags": [ { "name": "webdev", "keywords_for_search": "web development" }, { "name": "javascript", "keywords_for_search": "js" }, { "name": "beginners", "keywords_for_search": "" }, { "name": "codenewbie", "keywords_for_search": "" } ], "path": "/catalinmpit/best-resources-to-learn-javascript-as-a-beginner-4cjl", "comments_count": 0, "public_reactions_count": 26, "id": 424803, "published_at": "2020-08-11T15:56:48.336Z", "class_name": "Article", "user": { "name": "Catalin Pit", "id": 442205, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--R3rEXQkQ--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/442205/572f3ad9-94ed-4392-b478-1945e5f7809b.jpg", "username": "catalinmpit" }, "tag_list": ["webdev", "javascript", "beginners", "codenewbie"], "flare_tag": null, "user_id": 442205, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": "https://res.cloudinary.com/practicaldev/image/fetch/s--lTmZnHcv--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/ieucrtuqfgmjiar7q8o5.png", "title": "Best Resources To Learn JavaScript As A Beginner" }, "_score": null, "published_at_int": 1597161408, "published_timestamp": "2020-08-11T15:56:48.336Z" } ], "display_jobs_banner": true, "jobs_url": "https://jobs.dev.to/" } ```

and when I call the next page https://dev.to/search/feed_content?per_page=15&page=2&sort_by=hotness_score&sort_direction=desc&approved=&class_name=Article I get

Click to see full JSON response ```json { "result": [ { "reading_time": 1, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "TC39er.us with Allen Wirfs-Brock!", "video_duration_string": "0:00", "tags": [ { "name": "javascript", "keywords_for_search": "js" }, { "name": "podcast", "keywords_for_search": "" } ], "path": "/hemanth/tc39er-us-with-allen-wirfs-brock-1oci", "comments_count": 0, "public_reactions_count": 1, "id": 424714, "published_at": "2020-08-11T14:05:00.541Z", "class_name": "Article", "user": { "name": "hemanth.hm", "id": 697, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--kuu-illS--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/697/18315.jpeg", "username": "hemanth" }, "tag_list": ["javascript", "podcast"], "flare_tag": null, "user_id": 697, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "TC39er.us with Allen Wirfs-Brock!" }, "_score": null, "published_at_int": 1597154700, "published_timestamp": "2020-08-11T14:05:00.541Z" }, { "reading_time": 1, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Tonight Live [6PM IST] - Building SSR React Micro Frontends | By Ruben Casas \u0026 Nelly Kiboi", "video_duration_string": "0:00", "tags": [ { "name": "webdev", "keywords_for_search": "web development" }, { "name": "tutorial", "keywords_for_search": null }, { "name": "javascript", "keywords_for_search": "js" }, { "name": "react", "keywords_for_search": "" } ], "path": "/nialljoemaher/tonight-live-6pm-ist-building-ssr-react-micro-frontends-by-ruben-casas-nelly-kiboi-3b5g", "comments_count": 0, "public_reactions_count": 1, "id": 424728, "published_at": "2020-08-11T14:42:49.408Z", "class_name": "Article", "user": { "name": "Niall Maher", "id": 166066, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--2vWjHNcw--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/166066/40e6eec8-363d-45de-848c-7b04f3cd2603.png", "username": "nialljoemaher" }, "tag_list": ["webdev", "tutorial", "javascript", "react"], "flare_tag": null, "user_id": 166066, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "Tonight Live [6PM IST] - Building SSR React Micro Frontends | By Ruben Casas \u0026 Nelly Kiboi" }, "_score": null, "published_at_int": 1597156969, "published_timestamp": "2020-08-11T14:42:49.408Z" }, { "reading_time": 2, "main_image": "https://res.cloudinary.com/practicaldev/image/fetch/s--NXIv1b7d--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/e1yi8l09i85mcu009nm2.png", "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "GSoC 20: Week 10", "video_duration_string": "0:00", "tags": [ { "name": "gsoc", "keywords_for_search": null }, { "name": "opensource", "keywords_for_search": "" }, { "name": "python", "keywords_for_search": "" } ], "path": "/nirajkamdar/gsoc-20-week-10-26jd", "comments_count": 0, "public_reactions_count": 1, "id": 424711, "published_at": "2020-08-11T16:11:52.926Z", "class_name": "Article", "user": { "name": "Niraj Kamdar", "id": 385879, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--fqNjKcjw--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/385879/70d45e15-520e-40e9-bca5-e6d504a02e00.jpeg", "username": "nirajkamdar" }, "tag_list": ["gsoc", "opensource", "python"], "flare_tag": null, "user_id": 385879, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": "https://res.cloudinary.com/practicaldev/image/fetch/s--NXIv1b7d--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/e1yi8l09i85mcu009nm2.png", "title": "GSoC 20: Week 10" }, "_score": null, "published_at_int": 1597162312, "published_timestamp": "2020-08-11T16:11:52.926Z" }, { "reading_time": 4, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "HMAC and MACs – The Inner Workings of JWTs", "video_duration_string": "0:00", "tags": [ { "name": "cryptography", "keywords_for_search": null }, { "name": "security", "keywords_for_search": null }, { "name": "authentication", "keywords_for_search": null } ], "path": "/wagslane/hmac-and-macs-the-inner-workings-of-jwts-4e55", "comments_count": 0, "public_reactions_count": 3, "id": 419832, "published_at": "2020-08-05T09:09:00.000Z", "class_name": "Article", "user": { "name": "Lane Wagner", "id": 169444, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--KS7knTLp--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/169444/b165e595-ca4b-4072-b620-3c50429f610c.png", "username": "wagslane" }, "tag_list": ["cryptography", "security", "authentication"], "flare_tag": null, "user_id": 169444, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "HMAC and MACs – The Inner Workings of JWTs" }, "_score": null, "published_at_int": 1596618540, "published_timestamp": "2020-08-05T09:09:00.000Z" }, { "reading_time": 4, "main_image": "https://dev-to-uploads.s3.amazonaws.com/i/o8hmmvfrytb2enwln458.png", "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Saying Goodbye to PhoneGap", "video_duration_string": "0:00", "tags": [ { "name": "javascript", "keywords_for_search": "js" }, { "name": "react", "keywords_for_search": "" }, { "name": "ionic", "keywords_for_search": null }, { "name": "webdev", "keywords_for_search": "web development" } ], "path": "/ionic/saying-goodbye-to-phonegap-1gp4", "comments_count": 0, "public_reactions_count": 17, "organization": { "name": "Ionic", "id": 845, "slug": "ionic", "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--J3HNJwY5--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/organization/profile_image/845/0adbf602-5848-43dd-a883-a558ceba10f4.png" }, "id": 424760, "published_at": "2020-08-11T15:40:30.091Z", "class_name": "Article", "user": { "name": "Max Lynch", "id": 77831, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--E8MsqrvG--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/77831/969830a3-2c91-4715-b84d-d28a2d433dde.jpg", "username": "maxlynch" }, "tag_list": ["javascript", "react", "ionic", "webdev"], "flare_tag": null, "user_id": 77831, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": "https://dev-to-uploads.s3.amazonaws.com/i/o8hmmvfrytb2enwln458.png", "title": "Saying Goodbye to PhoneGap" }, "_score": null, "published_at_int": 1597160430, "published_timestamp": "2020-08-11T15:40:30.091Z" }, { "reading_time": 5, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "How to Write A Podcast Episode", "video_duration_string": "0:00", "tags": [ { "name": "podcast", "keywords_for_search": "" }, { "name": "writing", "keywords_for_search": null } ], "path": "/supremerumham/how-to-write-a-podcast-episode-3ig6", "comments_count": 0, "public_reactions_count": 0, "id": 420636, "published_at": "2020-08-06T15:00:00.000Z", "class_name": "Article", "user": { "name": "Alex", "id": 145702, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--aUPCsPAq--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/145702/e7cbb9fa-c1da-484f-b317-f1a5f63a3f9d.jpeg", "username": "supremerumham" }, "tag_list": ["podcast", "writing"], "flare_tag": null, "user_id": 145702, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "How to Write A Podcast Episode" }, "_score": null, "published_at_int": 1596726000, "published_timestamp": "2020-08-06T15:00:00.000Z" }, { "reading_time": 2, "main_image": "https://dev-to-uploads.s3.amazonaws.com/i/r6wig19wzxlb96jg5rda.jpg", "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Conditional CSS Classes in HAML", "video_duration_string": "0:00", "tags": [ { "name": "rails", "keywords_for_search": null }, { "name": "haml", "keywords_for_search": null }, { "name": "webdev", "keywords_for_search": "web development" } ], "path": "/eclecticcoding/title-c8c", "comments_count": 0, "public_reactions_count": 2, "id": 424621, "published_at": "2020-08-11T12:37:33.374Z", "class_name": "Article", "user": { "name": "Chuck ", "id": 69818, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--NXpwQVyN--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/69818/4ac54d27-6960-4a16-9615-bfbff7176484.jpg", "username": "eclecticcoding" }, "tag_list": ["rails", "haml", "webdev"], "flare_tag": null, "user_id": 69818, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": "https://dev-to-uploads.s3.amazonaws.com/i/r6wig19wzxlb96jg5rda.jpg", "title": "Conditional CSS Classes in HAML" }, "_score": null, "published_at_int": 1597149453, "published_timestamp": "2020-08-11T12:37:33.374Z" }, { "reading_time": 6, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Building a Calendar Scheduling App Backend with Hasura Scheduled Triggers", "video_duration_string": "0:00", "tags": [ { "name": "scheduling", "keywords_for_search": null }, { "name": "backend", "keywords_for_search": null }, { "name": "hasura", "keywords_for_search": null }, { "name": "graphql", "keywords_for_search": "" } ], "path": "/hasurahq_staff/building-a-calendar-scheduling-app-backend-with-hasura-scheduled-triggers-5fge", "comments_count": 0, "public_reactions_count": 3, "id": 423298, "published_at": "2020-08-10T04:30:00.000Z", "class_name": "Article", "user": { "name": "Hasura", "id": 148148, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--3_EMdpcW--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/148148/60ae3367-79ba-422e-a393-c13d5fb71752.png", "username": "hasurahq_staff" }, "tag_list": ["scheduling", "backend", "hasura", "graphql"], "flare_tag": null, "user_id": 148148, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "Building a Calendar Scheduling App Backend with Hasura Scheduled Triggers" }, "_score": null, "published_at_int": 1597033800, "published_timestamp": "2020-08-10T04:30:00.000Z" }, { "reading_time": 1, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Diagrama do Ciclo de Vida Vue.js", "video_duration_string": "0:00", "tags": [{ "name": "vue", "keywords_for_search": "" }], "path": "/alexandrefreire/diagrama-do-ciclo-de-vida-vue-js-16dn", "comments_count": 0, "public_reactions_count": 1, "id": 424750, "published_at": "2020-08-11T14:59:13.410Z", "class_name": "Article", "user": { "name": "Alexandre Freire", "id": 213434, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--Jcgsf-kw--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/213434/f0871fa9-dddc-4660-8dd7-938759cd0115.jpg", "username": "alexandrefreire" }, "tag_list": ["vue"], "flare_tag": null, "user_id": 213434, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "Diagrama do Ciclo de Vida Vue.js" }, "_score": null, "published_at_int": 1597157953, "published_timestamp": "2020-08-11T14:59:13.410Z" }, { "reading_time": 1, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Recommendations to speed up a web application", "video_duration_string": "0:00", "tags": [ { "name": "react", "keywords_for_search": "" }, { "name": "javascript", "keywords_for_search": "js" }, { "name": "webdev", "keywords_for_search": "web development" }, { "name": "discuss", "keywords_for_search": "" } ], "path": "/kamo/recommendations-to-speed-up-a-web-application-2b37", "comments_count": 1, "public_reactions_count": 0, "flare_tag_hash": { "text_color_hex": "#FFFFFF", "name": "discuss", "bg_color_hex": "#000000" }, "id": 424861, "published_at": "2020-08-11T17:07:20.697Z", "class_name": "Article", "user": { "name": "KAIDI", "id": 335131, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--p9nPCsdD--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/335131/bd364562-2329-424b-ade3-775c39179ba7.png", "username": "kamo" }, "tag_list": ["react", "javascript", "webdev", "discuss"], "flare_tag": { "text_color_hex": "#FFFFFF", "name": "discuss", "bg_color_hex": "#000000" }, "user_id": 335131, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "Recommendations to speed up a web application" }, "_score": null, "published_at_int": 1597165640, "published_timestamp": "2020-08-11T17:07:20.697Z" }, { "reading_time": 9, "main_image": "https://images.pexels.com/photos/1569076/pexels-photo-1569076.jpeg", "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "How to Prepare for a Technical Interview", "video_duration_string": "0:00", "tags": [ { "name": "webdev", "keywords_for_search": "web development" }, { "name": "career", "keywords_for_search": "" }, { "name": "productivity", "keywords_for_search": "" }, { "name": "beginners", "keywords_for_search": "" } ], "path": "/jacobjzhang/how-to-prepare-for-a-technical-interview-4f24", "comments_count": 0, "public_reactions_count": 30, "id": 424663, "published_at": "2020-08-11T13:12:55.563Z", "class_name": "Article", "user": { "name": "Jake Z.", "id": 147628, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--NiaC4B67--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/147628/a2b1bd84-408b-4155-83b0-cd968a91f5a8.jpg", "username": "jacobjzhang" }, "tag_list": ["webdev", "career", "productivity", "beginners"], "flare_tag": null, "user_id": 147628, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": "https://images.pexels.com/photos/1569076/pexels-photo-1569076.jpeg", "title": "How to Prepare for a Technical Interview" }, "_score": null, "published_at_int": 1597151575, "published_timestamp": "2020-08-11T13:12:55.563Z" }, { "reading_time": 1, "main_image": "https://res.cloudinary.com/practicaldev/image/fetch/s--4cozB1_8--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/ova654dhs74ncqeid851.png", "readable_publish_date_string": "Aug 11", "cloudinary_video_url": "https://res.cloudinary.com/practicaldev/image/fetch/s--D6BQIX6R--/c_limit,f_auto,fl_progressive,q_80,w_880/https://dw71fyauz7yz9.cloudfront.net/video-upload__c9d9197798da143cea30cef30dcefc10/thumbs-video-upload__c9d9197798da143cea30cef30dcefc10-00001.png", "video_duration_in_minutes": 3, "title": "Switch Statement In Javascript | Javascript Crash Course", "video_duration_string": "3:43", "tags": [ { "name": "javascript", "keywords_for_search": "js" }, { "name": "tutorial", "keywords_for_search": null }, { "name": "webdev", "keywords_for_search": "web development" }, { "name": "codenewbie", "keywords_for_search": "" } ], "path": "/shubhamsaurav/switch-statement-in-javascript-javascript-crash-course-95k", "comments_count": 0, "public_reactions_count": 3, "id": 422613, "published_at": "2020-08-11T12:52:20.606Z", "class_name": "Article", "user": { "name": "Shubham Saurav", "id": 203431, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--5ZAPluoO--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/203431/6f3394bf-687e-4269-ba18-4bee8c4a5534.jpg", "username": "shubhamsaurav" }, "tag_list": ["javascript", "tutorial", "webdev", "codenewbie"], "flare_tag": null, "user_id": 203431, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": "https://res.cloudinary.com/practicaldev/image/fetch/s--4cozB1_8--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/ova654dhs74ncqeid851.png", "title": "Switch Statement In Javascript | Javascript Crash Course" }, "_score": null, "published_at_int": 1597150340, "published_timestamp": "2020-08-11T12:52:20.606Z" }, { "reading_time": 5, "main_image": "https://res.cloudinary.com/practicaldev/image/fetch/s--hTl0m4VQ--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/gt5huwgno49ptx6hf8pr.jpg", "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Understanding of self and this in PHP", "video_duration_string": "0:00", "tags": [{ "name": "php", "keywords_for_search": "" }], "path": "/programmingdive/understanding-of-self-and-this-in-php-6oc", "comments_count": 0, "public_reactions_count": 1, "id": 424833, "published_at": "2020-08-11T16:35:53.554Z", "class_name": "Article", "user": { "name": "Programming Dive", "id": 408383, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--3-O_bAWu--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/408383/a41cd498-219b-4b3f-a67d-2ccfee28fbcb.jpg", "username": "programmingdive" }, "tag_list": ["php"], "flare_tag": null, "user_id": 408383, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": "https://res.cloudinary.com/practicaldev/image/fetch/s--hTl0m4VQ--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/gt5huwgno49ptx6hf8pr.jpg", "title": "Understanding of self and this in PHP" }, "_score": null, "published_at_int": 1597163753, "published_timestamp": "2020-08-11T16:35:53.554Z" }, { "reading_time": 1, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Passando parâmetros para um Stateful Widget no Flutter", "video_duration_string": "0:00", "tags": [{ "name": "dart", "keywords_for_search": "dartlang" }], "path": "/alexandrefreire/passando-parametros-para-um-stateful-widget-no-flutter-2im5", "comments_count": 0, "public_reactions_count": 1, "id": 424747, "published_at": "2020-08-11T14:51:32.742Z", "class_name": "Article", "user": { "name": "Alexandre Freire", "id": 213434, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--Jcgsf-kw--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/213434/f0871fa9-dddc-4660-8dd7-938759cd0115.jpg", "username": "alexandrefreire" }, "tag_list": ["dart"], "flare_tag": null, "user_id": 213434, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "Passando parâmetros para um Stateful Widget no Flutter" }, "_score": null, "published_at_int": 1597157492, "published_timestamp": "2020-08-11T14:51:32.742Z" }, { "reading_time": 1, "main_image": null, "readable_publish_date_string": "Aug 11", "cloudinary_video_url": null, "video_duration_in_minutes": 0, "title": "Build Failed with an Exception – Unable to merge dex", "video_duration_string": "0:00", "tags": [], "path": "/alexandrefreire/build-failed-with-an-exception-unable-to-merge-dex-b83", "comments_count": 0, "public_reactions_count": 1, "id": 424753, "published_at": "2020-08-11T15:02:30.318Z", "class_name": "Article", "user": { "name": "Alexandre Freire", "id": 213434, "pro": null, "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--Jcgsf-kw--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/213434/f0871fa9-dddc-4660-8dd7-938759cd0115.jpg", "username": "alexandrefreire" }, "tag_list": [], "flare_tag": null, "user_id": 213434, "highlight": null, "readable_publish_date": "Aug 11", "podcast": { "slug": null, "image_url": null, "title": "Build Failed with an Exception – Unable to merge dex" }, "_score": null, "published_at_int": 1597158150, "published_timestamp": "2020-08-11T15:02:30.318Z" } ], "display_jobs_banner": true, "jobs_url": "https://jobs.dev.to/" } ```

between those two API calls article with title TC39er.us with Allen Wirfs-Brock!' repeats. I tried the API calls couple of times I was able to recreate this in the first two pages (this happens in current dev.to). I am yet to reproduce this in local.

Rafi993 commented 3 years ago

Is this related to elastic search (app/services/search/query_builders/feed_content.rb)? @thepracticaldev/oss can you help me out here (Thanks in advance for taking your time to read my comments).

citizen428 commented 3 years ago

@Rafi993 The team name changed with the repo move, to ping us you now need to use @forem/oss :smiley:

For your actual question, I'll leave it to someone who is more familiar with the feed, maybe @joshpuetz can weigh in here?

joshpuetz commented 3 years ago

I suspect this might be some sort of collision between the articles we pull back directly from the database/cache (it's the first 10-30 IIRC), and the rest of the feed which comes back from Elasticsearch. I'm unsure if we actually check to eliminate duplicates!

One idea would be to record the article ids serviced initially, and exclude them from showing in the sets retrieved from Elasticsearch

Rafi993 commented 3 years ago

I suspect this might be some sort of collision between the articles we pull back directly from the database/cache (it's the first 10-30 IIRC), and the rest of the feed which comes back from Elasticsearch. I'm unsure if we actually check to eliminate duplicates!

One idea would be to record the article ids serviced initially, and exclude them from showing in the sets retrieved from Elasticsearch

I think you are right I couldn't find any code that checks to eliminate duplicates. So if the issue is due collision between database/ cache and elastic search then there shouldn't be any duplicates after first 30 articles right? (I'll try to verify this).

joshpuetz commented 3 years ago

I think you are right I couldn't find any code that checks to eliminate duplicates. So if the issue is due collision between database/ cache and elastic search then there shouldn't be any duplicates after first 30 articles right? (I'll try to verify this).

Yes, fantastic point @Rafi993! Duplicates occurring only between the very beginning and later in the feed would indicate this is the problem!

Rafi993 commented 3 years ago

I suspect this might be some sort of collision between the articles we pull back directly from the database/cache (it's the first 10-30 IIRC), and the rest of the feed which comes back from Elasticsearch. I'm unsure if we actually check to eliminate duplicates!

One idea would be to record the article ids serviced initially, and exclude them from showing in the sets retrieved from Elasticsearch

You were right the duplication occurs only within the first 30 entries. That is between url https://dev.to/search/feed_content?per_page=15&page=1&sort_by=hotness_score&sort_direction=desc&approved=&class_name=Article

and

https://dev.to/search/feed_content?per_page=15&page=2&sort_by=hotness_score&sort_direction=desc&approved=&class_name=Article

after that there is no duplication

Rafi993 commented 3 years ago

I suspect this might be some sort of collision between the articles we pull back directly from the database/cache (it's the first 10-30 IIRC), and the rest of the feed which comes back from Elasticsearch. I'm unsure if we actually check to eliminate duplicates! One idea would be to record the article ids serviced initially, and exclude them from showing in the sets retrieved from Elasticsearch

You were right the duplication occurs only within the first 30 entries. That is between url https://dev.to/search/feed_content?per_page=15&page=1&sort_by=hotness_score&sort_direction=desc&approved=&class_name=Article

and

https://dev.to/search/feed_content?per_page=15&page=2&sort_by=hotness_score&sort_direction=desc&approved=&class_name=Article

after that there is no duplication

Weirdly enough this not happening in my local development environment with same API calls.

rhymes commented 3 years ago

@Rafi993 are you still working on this? I know you're assigned to quite a few issues so it's understandable if you haven't gotten the time to get back to this. Let me know if you still want to work on this or else if you have new information you can leave in the issue here so to pass the torch if you decide so. Thank you!

Rafi993 commented 3 years ago

@Rafi993 are you still working on this? I know you're assigned to quite a few issues so it's understandable if you haven't gotten the time to get back to this. Let me know if you still want to work on this or else if you have new information you can leave in the issue here so to pass the torch if you decide so. Thank you!

Thank you @rhymes I was not able to recreate this issue in local even though it happens in dev.to. Please feel free to remove me as assignee from this issue so that If someone is able to recreate this issue again they could take it up.

Rafi993 commented 3 years ago

I have removed myself as assignee from this issue so that if anyone is able to recreate this issue in local environment can take it up.