AngularJS: How to use the $ q promise function in this situation to wait for the data to be ready?

I have a Controller that triggers an API call in a Factory . I am currently running a call, after that I have a function after this call to check the status Array

. However, I'm not sure how to make it wait here while data is being collected, so some implementation is needed $q

.

As you can see in the screenshot below, it vs.tickers

returns an empty object or array. Then finally the console.log

GetTickersFactory runs:

enter image description here

1st controller

if (root.tickerType === 'portfolio') {

    // Call to factory to start the API GETS:
    GetTickersFactory.getTickers('portfolio');

    // I then call a function in the Factory to return the array
    // Which isn't ready yet of course since it returns undefined...
    vs.tickers = GetTickersFactory.returnPortfolioTickers();

    console.log('portfolio');
    console.log('vs.tickers = ', vs.tickers);
}

      

getTickers function in GetTickersFactory | Maybe this helps: Gist for the complete Factory .

function getTickers(type, load, searchedTicker) {
    load = load || loadString; searchedTicker = searchedTicker || '';

    var portfolioTickersArray = [], searchedTickersArray  = [];

    tickersPane.loadingTickersDone = false;

    switch(type) {
        case 'searched':
            ....
            break;

        case 'portfolio':

            if (portfolioCached) {
                // The API Call (cached)
                ApiFactory.getWatchList().then(function(data) {
                    portfolioTickersArray = renderTickers(data.data.tickers, undefined, type);
                    portfolioTickers.that = portfolioTickersArray;
                    tickersPane.loadingTickersDone = true;
                    console.log('portfolioTickersArray: ', portfolioTickersArray);
                    return portfolioTickersArray;
                });

            } else {
                // The API Call (not cached)
                ApiFactory.getWatchListRefresh().then(function(data) {
                    portfolioTickersArray = renderTickers(data.data.tickers, undefined, type);
                    portfolioTickers.that = portfolioTickersArray;
                    portfolioCached = true;
                    tickersPane.loadingTickersDone = true;
                    console.log('portfolioTickersArray: ', portfolioTickersArray);
                    return portfolioTickersArray;
                });
            }
            break;
    }

    function renderTickers(data, searchedTicker, type) {
        ....
    }
}

      

The returned array function that I am using inside getTickersFactory.js. I suppose I shouldn't be using this, but figure out how to use promises instead:

function returnPortfolioTickers() {
    return portfolioTickers.that;
}

      


Note. I tried this first, but with the same results:

vs.tickers = GetTickersFactory.getTickers('portfolio');

      

vs.tickers

will return undefined

+3


source to share


3 answers


Your switch cases must return a promise for the caller to call .then

when the promise has been resolved.

Factory Code

function getTickers(type, load, searchedTicker) {
    //other code remains same
    tickersPane.loadingTickersDone = false;
    switch (type) {
        case 'searched':
            return ApiFactory.getTickers(null, load).then(function(data) {
                //other code remains same
                if (tickersPane.tempTickers.length > 0) {
                    //other code remains same
                    return returnData(searchedTickersArray);
                }
                return []; //return default variable to continue promise chain
            });
            break;
        case 'portfolio':
            tickersPane.addOption = false;
            tickersPane.removeOption = true;
            tickersPane.displayTopTags = false;
            tickersPane.displayPortfolio = true;

            if (portfolioCached) {
                return ApiFactory.getWatchList().then(function(data) {
                    //other code remains same
                    return returnData(portfolioTickersArray);
                });
            } else {
                return ApiFactory.getWatchListRefresh().then(function(data) {
                    //other code remains same
                    return returnData(portfolioTickersArray);
                });
            }
            break;
    }
    function renderTickers(data, searchedTicker, type) {
        //this should be as is
    }
    function returnData(data) {
        tickersPane.loadingTickersDone = true;
        return data;
    }
    //tickersPane.loadingTickersDone = true;
    //return data; //removed this line and move to function
}

      



controller

if (root.tickerType === 'portfolio') {
    // Call to factory to start the API GETS:
    GetTickersFactory.getTickers('portfolio').then(resp){
         vs.tickers = GetTickersFactory.returnPortfolioTickers();
         console.log('portfolio');
         console.log('vs.tickers = ', vs.tickers);
    };
}

      

+1


source


If you want to use ES6 promise:

function getTickers(type, load, searchedTicker) {

  return $q(function (resolve, reject) {

     if (doTheGoodThings()) {
       resolve('This is ok!');
     } else {
       reject('This did not work');
     }

  }
}

      



And then in your controller:

if (root.tickerType === 'portfolio') {

  GetTickersFactory.getTickers('portfolio').then(function (result) {
    console.log('Worked: ' + result);
  }, function (error) {
    console.log('Error: ' + error);
  });

}

      

+2


source


You already have two methods that return promises (getWatchList and getWatchListRefresh), so you can just return those methods and chain more .then

s. There is no need to use $ q here.

Hope this simplified example helps you in the right direction ...

function getTickers(type) {
    var tickers;

    switch(type) {
        // ...
        case 'portfolio': 
            var getList = portfolioCached ? getWatchList : getWatchListRefresh;
            // tickers will be set to the promise returned
            // by getWatchList or getWatchListRefresh
            tickers = getList().then(function(data) {
                if (!portfolioCached) {
                  portfolioCached = true;
                }
                // the result returned by renderTickers will be 
                // passed to any `.then` that is chained
                return renderTickers(data.data.tickers, undefined, type);
            });
        break;
    }

    // return the tickers promise
    return tickers;
}

      

Then in your controller:

// the `tickers` param here will be the result
// returned by renderTickers()
GetTickersFactory.getTickers('portfolio').then(function(tickers) {
    vs.tickers = tickers;
});

      

+1


source







All Articles