0

I'm trying to move all the business logic from my controller to the factory, but I'm having some trouble passing fields data.

factory.js

app.factory("Quote", function ($resource) {
    // TODO: this shouldn't start with /en/
    var quoteStatus = [];
    var quoteLanguage = [];

    var Quote = $resource("/en/quote/api/quote/:id", {}, {
        retrieve: {
          method: 'GET',
          params: {},
          isArray: true
        },
        query: {
          method: 'GET',
          params: {},
          isArray: true,
          url: '/en/quote/api/quote/'           
        },
        fields: {
          method: 'GET',
          url: '/en/quote/api/quote/fields/ '
        },
        update: {
          method: 'PATCH',
        },
    });

    Quote.fields().$promise.then(function (fields) {
        var tempObj = [];
        for (key in fields.status) {
            // must create a temp object to set the key using a variable
            tempObj[key] = fields.status[key];
            quoteStatus.push({
                value: key,
                text: tempObj[key]
            });
        }

        for (key in fields.language) {
            // must create a temp object to set the key using a variable
            tempObj[key] = fields.language[key];
            quoteLanguage.push({
                value: key,
                text: tempObj[key]
            });
        }

        //$scope.addLanguage($scope.language);

        Quote.status = quoteStatus;
        Quote.language = quoteLanguage;
    });

    return Quote;


});

controller.js

$scope.quoteStatus = Quote.status;

However this is not working since $scope.quoteStatus is undefined. What am I missing?

Thanks in advance.

1 Answer 1

2

You can't expect async operation to behave in synchronous way.

Basically when controller inject Quote in its factory function that time Quote service object gets created & then calls Quote.fields(). hen you ask Quote.status inside a controller will always return undefined. You are not maintaining promise anywhere so that controller will come to know that the data is ready or not.

I think you should introduce $q.when flag there to check the Quote.fields() operation completed or not & then do get the desired variable there.

For implementing above mention thing you need to store the promise of Quote.fields() call somewhere in service. like below

var quoteFieldsPromise = Quote.fields().$promise.then(function (fields) {

   /// the code will be same here

};

Then add new method which will hold of quoteFieldsPromise promise object and return the value of quoteStatus & quoteLanguage.

var getQuoteDetails = function(){
   $q.when(quoteFieldsPromise).then(function(){
      return { quoteStatus: Quote.quoteStatus, quoteLanguage: Quote.quoteLanguage };
   })
}

But the way you have returned whole Quote object, which only has $resource object which needs to be changed. I mean to say that the getQuoteDetails method which I've created can not be return with Quote object. So I'd rather rather refactor service to below.

Service

app.factory("Quote", function($resource, $q) {
    // TODO: this shouldn't start with /en/
    var quoteStatus = [], //kept private if needed
        quoteFieldsPromise, 
        quoteLanguage = [];//kept private if needed

    var QuoteApi = $resource("/en/quote/api/quote/:id", {}, {
        //inner code is as is 
    });

    //preserve promise of .fields() call
    quoteFieldsPromise = Quote.fields().$promise.then(function(fields) {
        //inner code is as is 
        //below lines are only changed.

        Quote.status = quoteStatus;
        Quote.language = quoteLanguage;
    });

    var getQuoteDetails = function() {
        return $q.when(quoteFieldsPromise).then(function() {
            return {
                quoteStatus: quoteStatus,
                quoteLanguage: quoteLanguage
            };
        })
    };

    return {
        QuoteApi: QuoteApi,
        getQuoteDetails: getQuoteDetails
    };
});

Controller

Quote.getQuoteDetails().then(function(quoteDetails){
    $scope.quoteStatus = quoteDetails.quoteStatus;
    $scope.quoteStatus = quoteDetails.quoteLanguage;
});
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Pankaj but how can I use getQuoteDetails in my controller? I've tried setting it like: Quote.prototype.quoteFields = function(){} in my factory.js but still appears undefined.
You helped me very much. Kindly appreciated.
@GustavoReyes Glad to hel you..Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.