-1

Current code is sloppy, I know. I am still iffy on then method.

What each get call returns

an array with some, not all, results

What I need

to pass two different uri and concatenate the result of both and then export it as module

e.g. getinfo(uri).getinfo(uri2).then(concatenated results)

CODE

const request = require('request-promise');

const getInfo = (uri) => {

    // Return new promise 
    return request({
      method: 'GET',
      uri: uri,
      json : true,
      headers: {
        'User-Agent': 'Request-Promise'
      }
    });
}

const promise = getInfo(url1).then((val) => {
  let store = [];
  getInfo(url2).then((val2) => {
    store = store.concat(val2.array);
    return store;
  })
});
//ideally
export promise;
user3241846
  • 643
  • 3
  • 9
  • 26
  • `store` is populated asynchronously, so examine it *after* the `.then`s, not before – CertainPerformance Oct 12 '18 at 03:43
  • @certainPerformance sure, I fixed the question to explain better. I dont know how to properly chain the calls. In the second `then` I know I have the correct result when I log it. Just need to return it properly – user3241846 Oct 12 '18 at 04:00
  • It's asynchronously populated, so you can't export the plain array (meaningfully), export a `Promise` instead – CertainPerformance Oct 12 '18 at 04:02
  • I think the duplicates are irrelevant - there's no indication that the OP doesn't understand asynchronous code - I believe https://pastebin.com/TZqCXqvJ is at least close to what they want – Jaromanda X Oct 12 '18 at 04:20
  • @JaromandaX Exactly! I dont know how to manipulate the `val` so that the final promise has both results when it is resolved, where it is imported. `url1` and `url2` are defined in same file. I removed them to keep it simple and private – user3241846 Oct 12 '18 at 04:22
  • you want to export a FUNCTION (that returns a promise), not a promise, because you want to `pass two different uri` - unless they are hard coded, then you'll need a function - see the above pasebin – Jaromanda X Oct 12 '18 at 04:23
  • one other question - do the requests need to be made one after the other, or can they be done in parallel? – Jaromanda X Oct 12 '18 at 04:24
  • They do not need to be done one after the other. I could have done them separately but thought chaining them would be cleaner and more elegant. Like you said, my struggling is with handling promises not the asynchronous concept. – user3241846 Oct 12 '18 at 04:26
  • https://pastebin.com/m5wb9zev in parallel – Jaromanda X Oct 12 '18 at 04:27
  • of course, I'm assuming the results of both requests will have an `array` property - but I'm sure you can figure that part out yourself as you know the data you're getting better than us :p – Jaromanda X Oct 12 '18 at 04:28
  • @JaromandaX sweet Jesus it worked!! Can you post this in an answer so I can accept it? Ill dig for documentation to understand how it works! Thanks!! – user3241846 Oct 12 '18 at 04:37
  • nevermind - question is re-opened now :p – Jaromanda X Oct 12 '18 at 04:45

1 Answers1

1

You just need to use .then correctly, and not discard the result of the first request

const request = require('request-promise');

const getInfo = (uri) => {

    // Return new promise 
    return request({
        method: 'GET',
        uri: uri,
        json : true,
        headers: {
            'User-Agent': 'Request-Promise'
        }
    });
}

// using promise.then

const result = (url1, url2) => getInfo(url1)
    .then(val1 => getInfo(url2)
        .then(val2 => val1.array.concat(val2.array))
    );

// or async/await

const result = async (url1, url2) => {
    const val1 = await getInfo(url1);
    const val2 = await getInfo(url2);
    return val1.array.concat(val2.array);
};

// both requests done at the same time

const result = (url1, url2) => Promise.all([
    getInfo(url1),
    getInfo(url2)
]).then(([val1, val2]) => val1.array.concat(val2.array));


export result;

// usage

const fn = require("./module.js"); // whatever you call the above file
fn("url1", "url2").then(result => {
    // use result here
});

To explain each incarnation of result - it may be easier to write it out using regular functions so I can add comments

const result = function(url1, url2) {
    return getInfo(url1)
    .then(function(val1) {
        return getInfo(url2)
        .then(function(val2) {
            return val1.array.concat(val2.array));
        })
    })
}

Usually you try to avoid "nesting" .then's like this, but since the end result requires both val1 and val2, it's unavoidable (not really, but, lets say it is)

This is where async/await shines

const result = async (url1, url2) => {
    const val1 = await getInfo(url1);
    const val2 = await getInfo(url2);
    return val1.array.concat(val2.array);
};

There's no need to even rewrite that, because it's clear!

However, you want to run in Parallel

const result = (url1, url2) => Promise.all([
    getInfo(url1),
    getInfo(url2)
]).then(([val1, val2]) => val1.array.concat(val2.array));

Promise.all takes an array of promises, and returns a promise that resolves to the array of resolved results

([val1, val2]) => //rest of code

in case you didn't know is like

(results => {
    let val1 = results[0];
    let val2 = results[1];
    // rest of code

So, that should be fairly easy to understand as it is

Jaromanda X
  • 53,868
  • 5
  • 73
  • 87