0

I am writing a code that would call DATA from JASON file. I had an asynchronous problem and saw many posts about same issue.

I wrote some code that I guess it would fix my problem. It, however, seems like the data is still not loaded.

I will be more specific with my question. I used promise method below. I thought 'questions' should not be returned before all the data is fully loaded. Apparently, 'questions', having nothing inside, is returned to my page.

Is my promise method correct? if not how can I fix this problem. Can someone please help me?

(function(){

angular
    .module("GrammarQuiz")
    .factory("DataService", DataFactory);
    function DataFactory($log, $q, $http, $timeout){
        var vm = this
        var questions = getData() ;
        vm.getData = getData;

        function getData(){
            var defer = $q.defer()
            $http.get('api/data1.json')
            .success(function(res){
                questions = res;
                $log.log('success');
                defer.resolve(res);
            })
            .error(function(err, status){
                $log.log('fail');
                defer.reject(err);
            })
            return defer.promise;
        }


        $log.log('check');
        $log.log(questions[0]);

        return questions;
    }  


})();
Taehun Ahn
  • 15
  • 5
  • Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Heretic Monkey Aug 15 '16 at 22:15
  • Yes I did see this post, but still cannot figure out the way to solve within my code. I am not sure what is the issue. :( – Taehun Ahn Aug 15 '16 at 22:16
  • This is race condition city here. You are deliberately delaying the http request of something to try and log it later or something? Either call a function in the success function, or use a promise. – ryanlutgen Aug 15 '16 at 22:17
  • You need to explain what you don't understand about that duplicate. [edit] your question and explain that. – Heretic Monkey Aug 15 '16 at 22:18
  • the reason why I have both timeout and promise is because promise method didn't work. so, I just added timeout before positing this question. this doesn't work without timeout anyway. – Taehun Ahn Aug 15 '16 at 22:19

2 Answers2

1

What you have shown is not the proper way to use Promises. Instead you should be doing something similar to the following:

Factory (Service)

.factory("DataService", DataFactory);

function DataFactory($http) {
    var service = {};
    service.getData = function () {
        return $http.get('api/data1.json')
            .then(function(response) {
                return response.data;
            });
        };
    return service;
}

Controller

.controller("MyController", MyController);

function MyController($scope, DataService) {
    $scope.questions = {}; // or $scope.questions = []; if the return type is an array
    DataService.getData()
        .then(function(data) {
            $scope.questions = data;
        })
        .catch(function(errorResponse) {
            // do something with the error
        });
}
Lex
  • 6,758
  • 2
  • 27
  • 42
0

You've got a couple problems with asynchronous code here, as you suggested in your post.

The first problem is that you're trying to log data that doesn't exist yet with this code:

$log.log(questions[0])

This is being run immediately after the request to get data so obviously the data hasn't been loaded yet. What will it print go the console? Probably undefined or something similar.

If you want to log your questions data, you need to do that in the $http.get success function.

    $http.get('api/data1.json')
    .success(function(res){
        questions = res;
        $log.log('success');
        $log.log(questions);
        defer.resolve(res);
    })

Secondly, you're creating a promis by using $q.defer but that's completely unnecessary because $http.get already returns a promise which is executed in the .success() function. So remove any extra promises to simplify your code and just use the $http.get.

And don't expect data to be available anywhere else except in the .success() function.

Dr. Cool
  • 3,713
  • 3
  • 22
  • 26
  • I do not want to log my questions data. I need 'questions' fully loaded with data and return it to the other controller so that I can use information in the data. Until now, questions is returned without any data. Could you tell me how to do it? or could you at least tell me a porper way of using promise? – Taehun Ahn Aug 15 '16 at 22:30