0
votes

Hopefully the code below communicates the problem clearly. The issue is that in the module which uses the get method of fetchData, the value being returned is the actual Promise, rather than the JSON as desired. Any thoughts on this?

// fetchData.js module
var _ = require('lodash');


function get() {
  var endpoint1 = `/endpoint1`;
  var endpoint2 = `/endpoint2`;

  return fetch(endpoint1)
    .then((endpoint1Response) => {
      return endpoint1Response.json()
        .then((endpoint1JSON) => {
          return fetch(endpoint2)
            .then((endpoint2Response) => {
              return endpoint2Response.json()
                .then((endpoint2JSON) => {
                  var data = _.merge({}, {json1: endpoint1JSON}, {json2: endpoint2JSON});
                  console.log('data in fetch', data); // this logs the json
                  return data;
                });
            });
        });
    });
}

exports.get = get;

// module which uses get method of fetchData get
var fetchData = require('fetchData');
var data = fetchData.get();
console.log('returned from fetchData', data); // this logs a Promise
1
Of course it is, the only way to get the value is to access it inside the function passed to a Promise's .then() method. - idbehold

1 Answers

1
votes

Yes, that's exactly what's supposed to happen. The whole point of promises is that their result value is not immediately available and that doesn't change just because you're obtaining one from a separate module.

You can access the value like this:

var fetchData = require('fetchData');
fetchData.get().then(data =>
    console.log('returned from fetchData', data);
);

Also note that you are using promises in a non-idiomatic way and creating a "tower of doom." This is much easier on the eyes and accomplishes the same thing:

function fetchJson(endpoint) {
    return fetch(endpoint)
        .then(endpointResponse => endpointResponse.json()); 
}

function get() {
    var endpoint1 = `/endpoint1`;
    var endpoint2 = `/endpoint2`;

    return Promise.all([fetchJson(endpoint1), fetchJson(endpoint2)])
        .then(responses => {
            var data = { json1: responses[0], json2: responses[1] };
            console.log('data in fetch', data); // this logs the json
            return data;
        });
}

Edit I haven't used async/await in JavaScript, but to answer your question, I presume this would work:

async function fetchJson(endpoint) {
    var res = await fetch(endpoint);
    return res.json();
}

async function get() {
    var endpoint1 = `/endpoint1`;
    var endpoint2 = `/endpoint2`;

    var data = { 
        json1: await fetchJson(endpoint1), 
        json2: await fetchJson(endpoint2) 
    };

    console.log('data in fetch', data); // this logs the json

    return data;
}

// module which uses get method of fetchData get
async function main() {
    var fetchData = require('fetchData');
    var data = await fetchData.get();
    console.log('returned from fetchData', data);
}

return main();