Retrieving data from an object only works in the original function

I’m having issues retrieving data from an object using JS on my website. I have a third party scrape Instagram posts and provides JSON to my website via a link. I’ve managed to retrieve this data from the link and manipulate it, but the problem comes when I try to change the displayed image every 5 seconds.

I took the solution from How to change an image every 5 seconds for example? and tried to adapt for my solution, however, I get an error where posts[index] is undefined even though it shouldn’t be.

posts = [];
let index = 0;

indexx = 0
$.getJSON('posts.json', function(data) {
    $.each(data, function(i, f) {
        posts[indexx] = f
        indexx = indexx + 1

console.log(posts) // returns all the posts
window.onload = change();

function change() {

    console.log(posts) // Returns the list of posts
    console.log(posts[index]) // Returns 'undefined'
    console.log(posts[1]) // Returns 'undefined'
    $('#instaimg').attr('src', posts[index]["mediaUrl"])

    if (index == 5) {
        index = 0;
      } else {
      setTimeout(change, 5000);

I’m not sure if I am missing something or whether my lack of JS knowledge is to blame, but if anyone could help it would be appreciated

>Solution :

Several issues with your code:

  • Your console.log(posts) will show an empty array because the ajax callback has not finished yet => move that inside the .getJSON callback function
  • You call change recursively every 5 sec, e.g your call stack will grow indefinitely
  • Use setInterval instead of setTimeout
  • Start the interval timer inside the .getJSON callback function, so that it starts once the fetched data is ready
  • Use .push() to add to an array, no need to keep track of the index
  • Use $(function() { to make sure the DOM is ready before you do any action
  • You use a hardcoded length 4 for your data length, reference the array size instead

Updated code:

let index = 0;
let posts = [];

$(function() {
  $.getJSON('posts.json', function(data) {
    //$.each(data, function(i, f) {
    //  posts.push(f);
    // It looks like data is the array you want to use, so:
    posts = data;
    setInterval(changeImage, 5000);

function changeImage() {
  $('#instaimg').attr('src', posts[index++]["mediaUrl"]);
  if(index > posts.length) {
    index = 0;

Leave a Reply