2

I'm working on a code/demo that allows me to pull data from nodeJS routes I built. The data comes through ok with no problem. On the front end, however, I'm having a weird problem that I cannot wrap my head around.

Since the backend works(think rest API), then I'll skip posting that code here. On the front end, this is what I have that pulls the data:

JavaScript:

    const firstFeedFromAPI = "http://localhost:1916/datapull1";
    const secondFeedFromAPI = "http://localhost:1916/datapull2";
    var dataFeedTotal = []; //this array stores all data fetched from api

function pullAllGamingFeeds(){
  
        fetch(firstFeedFromAPI)
            .then( response => {return response.json()})
            .then( function(data){

                for(let i=0; i<2; i++){

                    storyElements = {
                        storyMainURL: data[i].urlForStory,
                        storyFeaturedImageURL: data[i].storyThumbnailImage,
                        storyTitle: data[i].storyTitle,
                        storyMeta: data[i].storyMeta,
                        storyPublishedBy: data[i].publishedBy
                    }

                    dataFeedTotal.push(storyElements);


                }            
            });

        

        fetch(secondFeedFromAPI )
            .then( response => {return response.json()})
            .then( function(data){

                for(let i=0; i<2; i++){

                    storyElements = {
                        storyMainURL: data[i].urlForStory,
                        storyFeaturedImageURL: data[i].storyThumbnailImage,
                        storyTitle: data[i].storyTitle,
                        storyMeta: data[i].storyMeta,
                        storyPublishedBy: data[i].publishedBy
                    }

                    dataFeedTotal.push(storyElements);

                }

            });        
    }

Now, the plan is to populate the array dataFeedTotal with all the data fetched from both the fetches above. What I plan to do later on is to randomize it and then print it on the page. The problem that I am having is that...well, I can't even fully explain it(I'm lost), but below is what I have tried with examples. I removed other deeper tests to make sure the below code is clear.

Here is what I have/tried below:

When I do this:

console.log(typeof(dataFeedTotal));
console.log("This array has this many items(should be 4 topics overall, yet i get): " + dataFeedTotal.length);
console.log(dataFeedTotal); 

(And this is why I'm super lost) I get this:

enter image description here

As you can see, it says my array has ZERO items, yet, when I expand the next item underneath that(the array I mean), it obviously has items inside of it. Check it out.

enter image description here

And as you can see, the data is there. I've had to rework a bunch of my code trying to figure this out. Then I said let me keep playing with it to see if I can figure this out. Decided to add a timer to test and see if its a loading issue. So then I did:

setTimeout(() => {
   console.log(dataFeedTotal.length); 
        console.log(typeof(dataFeedTotal));
        console.log("This array has this many items(should be 4 topics overall, yet i get): " + dataFeedTotal.length);
        console.log(dataFeedTotal); 
}, 5000);

and this seemed to work. i now get this: enter image description here

But then now that I have it working with a timer, I figured the data is in, now I can loop through that array and post my findings on the front end HTML. So I then do this:

setTimeout(() => {
   for(let i = 0; i <dataFeedTotal.length; i++){
        console.log(dataFeedTotal[i]);

        feedDisplayWrapper.innerHTML += `
            <div class="col-3 storyActual">
                <div class="storyFeatPic">
                    <a href="${dataFeedTotal[i].urlForStory}" target="new">
                        <img src="${dataFeedTotal[i].storyThumbnailImage}" alt="" class="img-responsive">
                    </a>
                </div><!-- storyFeatPic ender -->

                <div class="storyExerpT">
                    <h1><a href="${dataFeedTotal[i].urlForStory}" target="new">${dataFeedTotal[i].storyTitle}</a></h1>
                    <div class="storyDate">${dataFeedTotal[i].storyMeta}</div>

                    <div class="publishedBy">published by <span class="pubByHighlight">${dataFeedTotal[i].publishedBy}</span></div>
                </div><!-- storyExerpT ender -->
                <div class="sourceFavicon"></div><!-- sourceFavicon ender -->                    
            </div>
        `;

   }
}, 5000);

and it either doesn't show up still, or I get this enter image description here

As you can see, portions of the HTML arent showing(undefined) even though the data array has the info). Also, to play with it more, I put the timer at 3 minutes instead of the 5 seconds you see there, it's always the same thing.

I'm spent lol. What am I doing wrong? Any ideas you guys can help with would be awesome because right now my head is about to explode. Im just getting back to developing after about 5 years off. This is my first project back and its kicking my @#%$@. Thanks in advance.

somdow
  • 6,268
  • 10
  • 40
  • 58
  • 2
    `fetch` does its work *asynchronously*, so the logging without the delay is being done before the work is complete, before anything has been pushed to the array. If you introduce a delay, you might (or might not) see that the `fetch` work is done (depending on whether the delay was long enough). Don't rely on a delay, instead use the [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that `fetch` returns so you know when its work is complete. – T.J. Crowder Feb 04 '22 at 08:10
  • 1
    This is because `fetch` (as all network operations in JS) is async. You need to learn a bit about async code and promises. It's unfortunately too much to put into a SO answer. – Marian Theisen Feb 04 '22 at 08:11
  • 1
    Side note: Your `fetch` calls are falling prey to the API footgun I describe on my anemic old blog [here](http://blog.niftysnippets.org/2018/06/common-fetch-errors.html). You need to check `response.ok` to see whether the HTTP call worked, `fetch` only rejects on *network* errors, not HTTP errors (like 404 or 500). – T.J. Crowder Feb 04 '22 at 08:11
  • https://medium.com/codex/javascript-promise-for-dummies-f3e763c2ec26 – Marian Theisen Feb 04 '22 at 08:12
  • 1
    hey @T.J.Crowder, I actually have your work/post in another tab waiting too. Saw it a day or two ago. Great post. I will look into promises more. I did do some research but wasnt sure if thats whre i needed to go next. But thank you all for your direction. I will go to all these now. – somdow Feb 04 '22 at 13:29
  • Happy coding! :-) – T.J. Crowder Feb 04 '22 at 13:33

0 Answers0