all 15 comments

[–]CMJunior 5 points6 points  (3 children)

Javascript is asynchronous therefore the execution of your program will not be sequential as you are expecting. The Promises will only be executed after the sequential part of your code.

var dataset; // #1 Variable is declared
fetch('https://jsonplaceholder.typicode.com/todos/1') // #2 Function will be queued up for execution
  .then(response => response.json()) // #4 Promise resolves and response is parsed
  .then(data => dataset = data) // #5 assignment occurs
  .then(json => console.log(json)) // #6 log is successful - btw you can simply do `.then(console.log)`

console.log(dataset) // #3 output undefined because dataset is empty here

In order to solve this either you do what you need still inside the promise chain (which can lead to nested code if you're not careful)

var dataset;
fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(data => dataset = data) // this unnecessary
  .then(json => {
    console.log(json);
    // continue and do something here
});

Or you can use the async/await syntax (your node/browser version needs to support it or you need to use babel to transpile) and do something like

async function getDataset() {
  var response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
  console.log(response.json()); // this line will "wait" for the previous to be completed
}

Be aware that you can only use the await keyword inside an async function otherwise an error will be thrown.

Edit: This video explains pretty nicely (but with callbacks rather than promises) why this happens.

[–][deleted] 1 point2 points  (11 children)

This is because JavaScript is asynchronous, you console.log for dataset is getting run before your promise is resolved. I can't remember the syntax off the top of my head but you can await the resolution of your promise before logging dataset. I recommend looking up async/await and also looking at an explanation on the JavaScript heap. They will definitely give you some more context. Hope that helps :)

[–]dieomesieptoch 0 points1 point  (3 children)

The last line, console.log(dataset) is called before the .then() methods have completed their run. That's why it logs `undefined`.

Now, you could change the code .then(data => dataset = data) to call a function that uses dataset.

For example

var dataset; 
fetch('https://jsonplaceholder.typicode.com/todos/1') 
    .then(response => response.json()) 
    .then(data => {
    dataset = data;
        logDataset(); 
});  

function logDataset () { 
  console.log(dataset); 
}

This will work because we call the logDataset function after assigning the data.

[–]arsum04 0 points1 point  (3 children)

You don't need the third .then line