0

I want my $http response data to be available to the controller, so as to display JSON data in the view via directive ("{{ hint }}"). However, while, in the controller, I can log data from the factory, the data will not provide itself in a useable manner.

When what is provided by the factory is logged in the controller, it is either "undefined" or "not a function". From the code below, "undefined" is logged"

Please, help me right my wrongs? How do I clean this up, so as to use factory's .GET data in the controller?

Controller:

var MainCtrl = angular.module('MainCtrl', []);

MainCtrl.controller('Ctrl2', [ "QuizViewServ", '$log', '$scope',
function(QuizViewServ, $log, $scope){


 $scope.init = function(){
    $scope.hint = "FooBar";  //Testing binding bw Ctrl2 & the view
    $log.log(QuizViewServ.getQuizData.quizQz); // <-LOGS AS "UNDEFINED"
 }

}]);

Factory:

var MainServ = angular.module('MainServ', []);

MainServ.factory('QuizViewServ', ['$http', function($http){
 console.log("factory working");

 var getQuizData = function(){

   $http({
      method: 'GET',
      url: '/assets/json.json'
    }).then(function successCallback(response) {
        console.log("inside successgul GET req");


        var quizQz;
        quizQz = response.data.quizQs;
        console.log(quizQz);


    }, function errorCallback(response) {

        alert("Trouble grabbing requested data.")
    });
  }
  return {
    getQuizData : getQuizData
  }

}]);
6
  • Read blog.ninja-squad.com/2015/05/28/angularjs-promises Commented May 12, 2016 at 19:42
  • @JBThis is a great article. Thanks. Commented May 13, 2016 at 10:12
  • ....He mispelled "pony", tho. :-/ ha. Commented May 13, 2016 at 12:35
  • Yeah, I know. I should fix that. I'm French-speaking, and pony is spelt poney here. Given that it looked to me like an English word, I thought it was spelt this way in English, too. Commented May 13, 2016 at 12:48
  • The author is you and your native tongue is French? Desole. You misspelled nothing. Again, great article. Thank you. Commented May 13, 2016 at 12:50

2 Answers 2

1

$http uses promises to return the result. When using QuizViewServ.getQuizData.quizQz you are logging nothing, since its asynchronous.

In your factory, return the promise, and in you controller, handle it.

var MainServ = angular.module('MainServ', []);

MainServ.factory('QuizViewServ', ['$http', function($http){
 console.log("factory working");

 var getQuizData = function(){

   return $http({
      method: 'GET',
      url: '/assets/json.json'
    })
  }
  return {
    getQuizData : getQuizData
  }

}]);

and in your controller

var MainCtrl = angular.module('MainCtrl', []);

MainCtrl.controller('Ctrl2', [ "QuizViewServ", '$log', '$scope',
function(QuizViewServ, $log, $scope){


 $scope.init = function(){
    $scope.hint = "FooBar";  //Testing binding bw Ctrl2 & the view

    QuizViewServ.getQuizData().then(function(result){
        $log.log(result.data);
    });
 }

}]);
Sign up to request clarification or add additional context in comments.

4 Comments

this does work. And for exactly the reasons you mentioned above, which I neglected. HOWEVER, doesn't this mean that the "business logic", of iterating through objects of the JSON file, has to stay in the Controller? For the sake of "cleanliness", should that logic be kept in the Service? ---I'm not disputing your answer, I'm genuinely curious.
It depends if you need to do different treatments with the returned data. If it is somewhat unique for every controller that uses it, you should do it within the controller. If multiple controller needs the same data, then do your data treatment in the factory using @Zohaib Ijaz 's solution, they are both valid :P So basically, you have the option of doing both ways, depends on the scenario and your personal preference
Gotcha. That totally makes sense. Yes, I've tried yours and @Zohaib Ijaz ' solutions. They both work, as you said, in diff circumstances. Thanks.
Glad we could help ! Please mark one of the answers as correct for other user's visiting this question later on
0

You need to retrun that data. It is not possible as you are doing. Also quizQz propert is private. You can not access it even after that value has been set after ajax call.

var getQuizData = function(){

return $http({
  method: 'GET',
  url: '/assets/json.json'
}).then(function successCallback(response) {
    console.log("inside successgul GET req");


    var quizQz;
    quizQz = response.data.quizQs;
    console.log(quizQz);
    return quizQz;

  }, function errorCallback(response) {

    alert("Trouble grabbing requested data.")
    return '';
});

}

and in controller , get data like this.

QuizViewServ.getQuizData().then(function(data){
    console.log(data);
});

8 Comments

You can't return data in a promise, You need to assign it to a variable that is declared outside of that promise, or return the object to handle the promis. My answer is the proper way to retrieve data from a promis. Return the function that returns the promis and handle it. : stackoverflow.com/questions/26854654/…
I am using angular in my production app and I know ,we can return data , however I missed to add return statement before $http()
Then you would have to $watch the result from getQuizData () that seems like bad practice if its the case, im curious as to how you do it
No, no need to watch. I don't want to say that, learn first .. let me give you a refrence
@AndrewDonovan, Look at this, if this is wrong , he can not get 337 up votes. Confirm first before rejecting someone's answer. stackoverflow.com/a/12513509/5567387
|

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.