0

The problem is that I want to print out myGlobalData which is the response to a fetching of data from a REST API, and later use it for generation of HTML.

I notice that I am able to print out the myLocalData to console.log, however am unable to print out the myGlobalData with console.log.

The problem is that the myGlobalData is unDefined.

Why is the myGlobalData result undefined? I have assigned the myGlobalData inside the mydata.then function to the text result, just like the myLocalData function.

Why is the myGlobalData unDefined, and the myLocalData a valid text response?


var fetch = require("node-fetch");
var http = require("http");
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: true });
let myGlobalData; 

// Running Server Details.
var server = app.listen(8082, function () {
  var host = server.address().address
  var port = server.address().port
  console.log("Example app listening at %s:%s Port", host, port)
});


app.get('/form', function (req, res) {
  var html='';
  html +="<body>";
  html += "<form action='/thank'  method='post' name='form1'>";
  html += "web URL:</p><input type='text' name='weburl'>";
  html += "<input type='submit' value='submit'>";
  html += "<INPUT type='reset'  value='reset'>";
  html += "</form>";
  html += "</body>";
  res.send(html);
});

app.post('/thank', urlencodedParser, function (req, res){

 var reply='';

 var mydata = fetch('https://facebook.github.io/react-native/movies.json');

 mydata.then(function(response) {
 return response.text()
 }).then(function(text) {

   // var myLocalData = text;

   myGlobalData = text; 

   myLocalData = text;

   console.log(myLocalData);
   });

   console.log(myGlobalData); // result is undefined Why?
joe the coder
  • 739
  • 2
  • 8
  • 15
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – SLaks May 17 '18 at 16:12

2 Answers2

0

Remember that fetch returns a promise, to get a value out you just need to return it, alternatively you can call another function from within the promise.

Here you can see three options for handling the data:

function handlerGlobalData(data) {
  // this could be myGlobalData
  console.log('Option #1: ' + data);
}

let myPromise = fetch('https://facebook.github.io/react-native/movies.json')
  .then(function(response) {
    // 'response' is the Response stream returned from fetch()
    return response.text();
  })
  .then(function(text) {
    // 'text' is the result of the resolved response.text() promise
    // Response.text() takes a Response stream and reads it to completion.
    // It returns a promise that resolves with a USVString (text).

    var myLocalData = text;

    console.log('myLocalData: ' + myLocalData);

    // (3) Option #1: pass 'text' to another function
    handlerGlobalData(text);

    return text;
  })
  .then(function(data) {
    // (4) Option #2: stay in this promise chain
    console.log('Option #2: ' + data);
    return data;
  });

// (1)
console.log('I was here first!');

// (5) Option #3
myPromise.then(function(data) {
  // this code can execute when 'myPromise' is resolved
  console.log('Option #3: ' +  data)  
});

// (2)
console.log('What about me?');

Expected order of output:

(1) I was here first!

(2) What about me?

(3) Option #1: ...

(4) Option #2: ...

(5) Option #3: ...

You should take the opportunity to familiarise yourself with the Fetch API and its Response interface.

Dan Nagle
  • 4,384
  • 1
  • 16
  • 28
  • Option #2 returned results. But Option#3 returned [object Object] – joe the coder May 17 '18 at 19:33
  • See follow up question about my sending reply message using res.send(reply). – joe the coder May 17 '18 at 19:44
  • Of course it doesn't work - you're not running the same code. – Dan Nagle May 17 '18 at 19:48
  • In your implementation you have `myPromise = fetch(...);`. Each `myPromise.then(...)` is going to receive the same object returned from `fetch(...)`. My implementation is `myPromise = fetch(...).then();` which returns the `response.text()` data from the fetch promise. – Dan Nagle May 17 '18 at 20:07
  • Thank you for your solution and help. I was able to see how Promises work now. Take a look at the final solution on how to send back the results using res.send(data) for the app.post results. – joe the coder May 17 '18 at 22:19
0
var fetch = require("node-fetch");
var http = require("http");
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: true });
let myGlobalData; 

// Running Server Details.
var server = app.listen(8082, function () {
  var host = server.address().address
  var port = server.address().port
  console.log("Example app listening at %s:%s Port", host, port)
});


app.get('/form', function (req, res) {
  var html='';
  html +="<body>";
  html += "<form action='/thank'  method='post' name='form1'>";
  html += "web URL:</p><input type='text' name='weburl'>";
  html += "<input type='submit' value='submit'>";
  html += "<INPUT type='reset'  value='reset'>";
  html += "</form>";
  html += "</body>";
  res.send(html);
});

app.post('/thank', urlencodedParser, function (req, res){

 let reply='';

 let myPromise = fetch('https://facebook.github.io/react-native/movies.json');

 myPromise.then(function(response) {
 return response.text()
 }).then(function(text) {

   // var myLocalData = text;

   myGlobalData = text; 

   myLocalData = text;

 //  console.log(myLocalData);
   return text;
   })
   .then(function(data) {
    // (4) Option #2: stay in this promise chain
    console.log('Option #2: ' + data);

    res.send(data);

    return data;
  });

 //  console.log(myGlobalData); // result is undefined Why?

// console.log(mydata);

myPromise.then(function(data) {
  // this code can execute when 'myPromise' is resolved
  console.log('Option #3: ' +  data);  
})

//reply += "Your URL submitted: " + myPromise.then(function(data) { 
  // console.log('Option #4' + data);

  // res.send(reply);

 // return data

// + myData; // req.body.weburl;
 // res.send(reply);

// fetch('http://localhost:8080/' + req.body.weburl)
//   .then(res => res.text())
//   .then(body => console.log(body))
//   .then(function(response) {

//   //  console.log(res.text());

//   console.log(response);

//   // reply += body;

//   //  res.send(body);
//   //  reply += data;

//   })    
//   .catch(function(error) {
//     console.log(error);
//   }); 




var locales = {
  europe: function() {          // The Europe continent's local scope
    var myFriend = "Monique";

    var france = function() {   // The France country's local scope
      var paris = function() {  // The Paris city's local scope
        console.log(myFriend);
      };

      paris();
    };

    france();
  }
};

locales.europe();

var test = "I'm global";

function testScope() {
  var test = "I'm local";

  console.log (test);     
}

testScope();           // output: I'm local

console.log(test);     // output: I'm global

var changeable;

function changeSomething(){ changeable = 'bla';}

changeSomething();
console.log(changeable);


  // mydata.then(response => {
  //   if(response.ok){
  //     response.json().then((data) => {

  //     myData = data;

  //     console.log(myData);

  //     res.send(myData);

  //  //   reply += data;

  //   //    console.log(data)

  //     });  
  //   }else{
  //     throw 'There is something wrong'
  //   }
  // }).
  // catch(error => {
  //     console.log(error);
  // });

// console.log(myData);


 });

Monique
I'm local
I'm global
bla
Option #3: [object Object]
Option #2: {
  "title": "The Basics - Networking",
  "description": "Your app fetched this from a remote endpoint!",
  "movies": [
    { "title": "Star Wars", "releaseYear": "1977"},
    { "title": "Back to the Future", "releaseYear": "1985"},
    { "title": "The Matrix", "releaseYear": "1999"},
    { "title": "Inception", "releaseYear": "2010"},
    { "title": "Interstellar", "releaseYear": "2014"}
  ]
}

The correct answer was Option #2, that helped by printing out the data results that were fetched from the myPromise contract. The results were sent using res.send(data), from the .then(function(data)) {

console.log('Option #2: ' + data);

res.send(data);

return data; }

joe the coder
  • 739
  • 2
  • 8
  • 15