azrael v
azrael v

Reputation: 281

How to use AngularJS $q deferred promises to return data from an async function?

I am having some troubles implementing AngularJS $q to get data from an async function and use it in an outer scope. Basically, I want to make the last line work in the below code. I have seen some examples but can't seem to wrap my head around AngularJS $q implementation.

var app = angular.module("myShoppingList", []);
        app.controller("myCtrl", function ($scope, $q) {

            const Papa = require('papaparse'); //I know these won't work, just added to give context
            const AWS = require('aws-sdk')

            AWS.config.update({
                //keys go here
            })

            const s3 = new AWS.S3()


            /* actual parameters should go here */
            const params = {
                Bucket: "test-bucket-2019",
                Key: "dummy.csv"
            };

            const parseOptions = {
                header: true,
                dynamicTyping: true /* will assume numbers are actually numbers, yada yada */
            }

        let deferred = this.$q.defer(); //how to use this???


            function getS3Data() {
                s3.getObject(params, function (err, data) {
                    if (err) console.log(err, err.stack);
                    else {
                        const csv = data.Body.toString('utf-8');
                        const headers = 'id,start,end,count';
                        const parsed = Papa.parse(headers + '\n' + csv, parseOptions);
                        var parsedData = parsed.data;
                        console.log(parsedData); //this works
                    }
                    return parsedData;

                })


            }
          console.log(parsedData) //how to make this work

        });

Upvotes: 0

Views: 329

Answers (2)

Pop-A-Stash
Pop-A-Stash

Reputation: 6652

Deferred is used to turn a callback function into a promise function.

function getS3Data() {
  let deferred = $q.defer(); 
  s3.getObject(params, function (err, data) {
    if (err) { 
      //console.log(err, err.stack);
      deferred.reject(err);
    }
    else {
      const csv = data.Body.toString('utf-8');
      const headers = 'id,start,end,count';
      const parsed = Papa.parse(headers + '\n' + csv, parseOptions);
      var parsedData = parsed.data;
      console.log(parsedData); //this works

      //return parsedData;  // do not return data
      deferred.resolve(parsedData);  // resolve the deferred with the data
    } 

  });
  return deferred.promise;  // important! return the promise, NOT THE DATA
}

When you call the function, you must define .then()/.catch() functions:

getS3Data().then(function(parsedData) {
   console.log(parsedData);
}).catch(function(err) {
  console.log(err, err.stack);
});

Upvotes: 0

Venkatesh Chitluri
Venkatesh Chitluri

Reputation: 134

One small edit required for the above answer, the return statement should be at the end of the function.

  function getS3Data() {
  let deferred = $q.defer(); 
  s3.getObject(params, function (err, data) {
    if (err) { 
      //console.log(err, err.stack);
      deferred.reject(err);
    }
    else {
      const csv = data.Body.toString('utf-8');
      const headers = 'id,start,end,count';
      const parsed = Papa.parse(headers + '\n' + csv, parseOptions);
      var parsedData = parsed.data;
      console.log(parsedData); //this works

      //return parsedData;  // do not return data
      deferred.resolve(parsedData);  // resolve the deferred with the data
    }
  });
 return deferred.promise;  // important! return the promise, NOT THE DATA
}

Upvotes: 1

Related Questions