0

I am trying to figure out, how to get this promise to a variable outside the scope.

var picture = JSON.stringify(this);
s.search('danbooru', { tags: ['cat'], limit: 1, random: true })
.then(images => console.log(images[0].common.fileURL))
.catch(err => console.error(err));

I can't find any possible soluton!

Sachin Rajput
  • 4,326
  • 2
  • 18
  • 29
Clearoi
  • 11
  • 1
    If the variable is defined outside of your functions scope (eg a global variable) you still have access to it and can save the results to the variable as you normally would (inside the `then` block, just go with `yourVariable = images[0].common.fileURL`.). – Philipp Meissner Jan 05 '18 at 08:07
  • 1
    `.then(images => variableInOuterScope = images)` – JLRishe Jan 05 '18 at 08:08

2 Answers2

-1

if s.search() returns a Promise, you sure can assign that Promise to a variable:

const searchPromise = s.search('danbooru', { tags: ['cat'], limit: 1, random: true });

searchpromise.then(images => console.log(images[0].common.fileURL))
.catch(err => console.error(err));

That would have its benefits (you can reuse the promise later). However, that is assigning a Promise to a variable, not the result of the promise:

if, instead, you want to assing the search result to a variable, you could do something like:

let images = null;

s.search('danbooru', { tags: ['cat'], limit: 1, random: true })
.then( img => {
    images = img;
})
.catch( ... )

However, you need to be sure that you will only access the images variable when the promise is settled:

bad:

let images = null;

s.search('danbooru', { tags: ['cat'], limit: 1, random: true })
.then( img => {
    images = img;
})
.catch( ... )

console.log(images); //bad, images will be null at this point.

fine:

let images = null;

s.search('danbooru', { tags: ['cat'], limit: 1, random: true })
    .then(img => {
        images = img;
        return anotherPromise();
    })
    .then(someResult => {
        console.log(someResult);
        console.log(images); //fine, images is guaranteed to be properly set at this point
    })
    .catch(... )

However, declaring mutable variables and assing them at some point in a promise chain could lead to issues. This really good SO thread assess the problem of reusing promise values and I'm pretty sure it will be useful to your issue.

Sergeon
  • 6,638
  • 2
  • 23
  • 43
  • Why would you want to return `anotherPromise` in the first place? If it's about receiving a promise at some end, you could simply return the original promise, no? – Philipp Meissner Jan 05 '18 at 08:19
  • Well, sometimes, in a promise chain, you need to reuse the value of a previous promise in another promise call. Like, you first grab an `user`, then you grab something that needs the user -lets say a `cardId`-, then you grab a third thing that needs both the user and the `cardId`: in such situation you would need to store the user in a variable. The code in my answer was only an example of a situation in which you can safely access the `images`var, doesn't pretend to be useful. – Sergeon Jan 05 '18 at 08:27
-1

how to get this promise to a variable outside the scope.

Don't. Use. Outside-scope. Variables.

Promises are about returning things. Return the promise chain. Return the values you want to work with. Work with them in the .then() callbacks.

Do not use global variables. Do not do work outside the promise chain.

function search(params) {
    return s.search('danbooru', params)
        .then(images => {
            /* do something with images[0].common.fileURL */
            return images;
        })
        .catch(err => console.error(err));
}

search({ tags: ['cat'], limit: 1, random: true }).then(images => {
    /* do something else with images[0].common.fileURL */
});

What you can do is store and re-use the promise itself.

var result = search({ tags: ['cat'], limit: 1, random: true });

/* ... do some things ... */

result.then(images => { /* do something with images */ });

/* ... do other things ... */

result.then(images => { /* do another thing with images */ });
Tomalak
  • 332,285
  • 67
  • 532
  • 628