-5

I'm still grappling with async await and often end up using a set timeout to quickly solve my problem hackily.

I'm getting data with jquery get and calling the buildSlideshow function on .done();

After the slideshow is built, I want to call the startSlideshow() function with another function.

I've tried various versions of async and await but can't seem to nail it, and without a timeout of some sort, the slideshow starts before it's fully build, with funky results.

$.get('/data/backgrounds.json').done((data) => {
      bgData = data;
      buildSlideshow(bgData.find(findVenue));
    });
  function findVenue(page) {
    return page.page === currentPage;
}

function buildSlideshow(page) {
  page.bgs.forEach((bg) => {
    bgUrl = bg.url ? bg.url : '';
    venueName = bg.venue ? bg.venue : '';
    venueLocation = bg.cityState ? bg.cityState : '';
    caption = `${venueName}<br>${venueLocation}`;
    div = document.createElement('div');
    $(div).append(caption);
    $(div).css('background-image', `linear-gradient(180deg, rgba(8, 0, 14, 0.3) 0%, rgba(8, 0, 14, 0) 100%), url(${bgUrl})`);
    $('#bgSlideshow').append(div);
  });
}

function startSlideshow() {
  $('#bgSlideshow > div:gt(0)').hide();

  setInterval(() => {
    $('#bgSlideshow > div:first')
      .fadeOut(2000)
      .next()
      .fadeIn(2000)
      .end()
      .appendTo('#bgSlideshow');
  }, 8000);
}
// doesn't work
startSlideshow();

// does work
setTimeout(() => {
  startSlideshow();
}, 300);
Kirk Ross
  • 6,413
  • 13
  • 61
  • 104
  • 1
    _"I'm getting data with jquery get and calling the buildSlideshow function on .done();"_ show that code. Most of your slideshow setup code here isn't too relevant. – Alex Wayne Sep 05 '19 at 20:21
  • 1
    unclear why you would need to use timeouts. What is asynchronous. I see nothing in that code that is. – epascarello Sep 05 '19 at 20:24
  • @AlexWayne I added the json call but it's not the problem. Getting / awaiting the data is not my problem, it's that the slideShow() starts before the forEach loop building the slideshow has appended all the divs. – Kirk Ross Sep 05 '19 at 20:54
  • 1
    @KirkRoss in fact, it starts before the forEach loop even begins. Even before the server receives the request for the slides. – Kevin B Sep 05 '19 at 21:28
  • 1
    Put the call to startSlideshow() after buildSlideshow()? – James Sep 05 '19 at 21:44

1 Answers1

-1

Stripping what's unimportant here you basically have this:

$.get('/data/backgrounds.json').done((data) => {
  buildSlideshow(data.find(findVenue));
});

startSlideshow();

What happens here is:

  1. You request your data, and provide a callback to run when that's done, bu t the fetch is pending.
  2. You start the slideshow.
  3. Sometime later, the request for data resolves and triggers your callback.

You simply need to move the call to startSlideshow into your callback where you build the slideshow, since you can't start it until you've built it.

$.get('/data/backgrounds.json').done((data) => {
  buildSlideshow(data.find(findVenue));
  startSlideshow();
});
Alex Wayne
  • 178,991
  • 47
  • 309
  • 337