Kai
Kai

Reputation: 780

Not receiving data in controller in Cordova Angular Ionic app

I have the following controller:

.controller('GitCtrl', function ($scope, $http, Chats) {
    $scope.search = function () {
        $id = 1;
        $scope.repos = Chats.all($http);
        $scope.repos2 = Chats.get($id);
    }
})

The only thing which does not work when I click a button which invokes the search function is Chats.all, which comes from the following service (along with Chats.get):

.factory('Chats', function ($http) {
  var chats = [{
    id: 0,
    name: 'Ben Sparrow',
    lastText: 'You on your way?',
    face: 'img/ben.png'
  }, {
    id: 1,
    name: 'Max Lynx',
    lastText: 'Hey, it\'s me',
    face: 'img/max.png'
  }];

  return {
    all: function () {
        var user = $('#gitdata-input').val();
        $http.get("https://api.github.com/users/" + user + '/repos').then(function (resp) {
            console.log('Success', resp);
            var repos = resp.data;
            return repos;
        }, function (err) {
            console.error('ERR', err);
        })
    },
    get: function(chatId) {
      for (var i = 0; i < chats.length; i++) {
        if (chats[i].id === parseInt(chatId)) {
          return chats[i];
        }
      }
      return null;
    }
  };
});

Chats.get and the chats array are merely for testing purposes.

I have verified that the service works, as I 'Succes' gets logged to my console and I also see that ver repos contains my data. In the controller however,$scope.repos stays undefined. $scope.repos2 does work.

Then I noticed in the console that the Chats.all function from the service (in which I have a breakpoint) gets called AFTER $scope.repos2 is already filled with the result of Chats.get. So why is this? And is it also what is causing me to not receive the data from Chats.All in my controller?

Upvotes: 0

Views: 75

Answers (2)

skubski
skubski

Reputation: 1606

The accepted answer is bad practice and should be avoided when possible.

An angular $http call is returning a promise and should not be wrapped in another promise ($q). It would suffice to return the promise of the $http call itself.

In short:

app.factory('Chats', function($http) {
  return {
    all: function(user) {
      return $http.get("https://api.github.com/users/" + user + "/repos")
                  .then(function(resp) {
                          return resp.data;
                    }, function(err) {
                          console.log('ERR', err);
                    });
    }
  };
});

should do the trick. (See plunker) and surely do read why wrapping promises in promises should be avoided here.

Upvotes: 1

Luke
Luke

Reputation: 2454

while Chats.get() and Chats.remove() are synchronous, the function Chats.all() is asynchronous since it contains an http call, hence when you do:

$scope.repos = Chats.all($http);

You are basically returning undefined. I would suggest you to use promises, hence changing your Chats.all() code to this:

all: function () {
    return $q(function(resolve,reject) {
        var user = $('#gitdata-input').val();
        $http.get("https://api.github.com/users/" + user + '/repos').then(function (resp) {
            console.log('Success', resp);
            resolve(resp.data);
        }, function (err) {
            reject(err);
        });
    }
},

And the line in the controller as following:

Chats.all($http).then(function(data) {$scope.repos = data;});

Cheers!

Upvotes: 1

Related Questions