$http.get not working at .factory

2019-09-05 01:28发布

问题:

I'm building a App with Ionic. To start, I create a project based on TABS template. So, after the creation, i'm trying to get my chats by an API but don't work. That's the code of services.js:

angular.module('starter.services', [])

.factory('Chats', function($http) {
  // Might use a resource here that returns a JSON array

  // Some fake testing data
  // 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'
  // }, {
  //   id: 2,
  //   name: 'Adam Bradleyson',
  //   lastText: 'I should buy a boat',
  //   face: 'img/adam.jpg'
  // }, {
  //   id: 3,
  //   name: 'Perry Governor',
  //   lastText: 'Look at my mukluks!',
  //   face: 'img/perry.png'
  // }, {
  //   id: 4,
  //   name: 'Mike Harrington',
  //   lastText: 'This is wicked good ice cream.',
  //   face: 'img/mike.png'
  // }];
  var chats = function(){ 
    $http.get("http://lucassmuller.com/work/projetoblog/api.php?action=posts")
    .success(function(data) {
        return data;
        console.log='data success';
    })
    .error(function(data) {
        console.log='data error';
    });
  }

  return {
    all: function() {
      return chats;
    },
    remove: function(chat) {
      chats.splice(chats.indexOf(chat), 1);
    },
    get: function(chatId) {
      for (var i = 0; i < chats.length; i++) {
        if (chats[i].id === parseInt(chatId)) {
          return chats[i];
        }
      }
      return null;
    }
  };
});

But this aren't working. That can I do to make the $http get the data of API!?

回答1:

First of all, I just changed it:

all: function() {
       return chats;
     },

for: all: chats,

Also, the methods success and error have been deprecated, according to this deprecation notice:

Deprecation Notice

The $http legacy promise methods success and error have been deprecated. Use the standard then method instead. If $httpProvider.useLegacyPromiseExtensions is set to false then these methods will throw $http/legacy error.

Here's is a snippet working:

 (function() {
   "use strict";
   angular.module('app', [])
     .controller('mainCtrl', function(Chats) {
       Chats.all();
     })

   .factory('Chats', function($http) {
     var chats = function() {
       $http.get("http://lucassmuller.com/work/projetoblog/api.php?action=posts").
       then(function(response) {
         console.log('$http.get worked!!');
       }, function (response) {
         console.log('error!!');
       });
     }
     return {
       all: chats,
       remove: function(chat) {
         chats.splice(chats.indexOf(chat), 1);
       },
       get: function(chatId) {
         for (var i = 0; i < chats.length; i++) {
           if (chats[i].id === parseInt(chatId)) {
             return chats[i];
           }
         }
         return null;
       }
     };
   });
 })();
<!DOCTYPE html>
<html ng-app="app">

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>

<body ng-controller="mainCtrl as main">

</body>

</html>



回答2:

Factory method needs to return the $http promise so that you can access data in controller when promise resolves

.factory('Chats', function($http) {

      function getChats(){
          // return promise from function
          return $http.get("http://lucassmuller.com/work/projetoblog/api.php?action=posts");
      }

      return {
          all: getChats
      }
}

now in controller you use then() of promise to assign your data to scope

Chats.all().then(function(response){
     $scope.chats = response.data;
});

Now if you want to store the array you can use another then() in the factory method:

.factory('Chats', function($http) {

  var factory = {
    chats: null,
    all: getChats
  };


  return factory;

  function getChats() {
    // return promise from function
    return $http.get("http://lucassmuller.com/work/projetoblog/api.php?action=posts").then(function(response) {
      factory.chats = response.data;
      return factory.chats;
    });
  }

});

And in controller

Chats.all().then(function(chats){
     $scope.chats = chats;
});


回答3:

Since the question is already answered, please allow me to point out an issue with your code that nobody cared to talk about.

You're using these in your code:

//..
console.log='data success';
// some code     
console.log='data error';

The correct way to use console.log is to pass a parameter to it since its a function. Rougly, your browser has code like this:

function console() {
  this.log = function() {
    // code that logs to the console
  }
}

When you do console.log = 'data success', you are assigning the string 'data success' to the log property of console object. There reference to the actual functional code is lost and console.log will not work the way it should for rest of the page.

console.log('I work fine');
console.log = 'I screw things up!';
console.log('I cannot log to the console'); // every `console.log`s below here do not work