6

Ich habe ein Projekt abgeholt und ich versuche, einige Daten von einem Dienst zu meinem Controller zurückgeben. Ich bin seit ungefähr 12 Stunden dabei und habe verschiedene Methoden ausprobiert. Sie alle führen normalerweise zu der gleichen Art von "fehlenden Daten".AngularJS: Controller-Bereich wird nicht mit Versprechen synchronisiert

Ich habe versucht

  • $ resource statt mit $ http
  • legte das $http.get direkt in den Controller ohne Versprechungen
  • der Dienst als Ist-Service (statt einer Fabrik) ohne eine Rückkehr
  • Aufbau der Fabrik eine Reihe von verschiedenen Möglichkeiten, um Daten in einer Vielzahl von Formaten
  • mit setTimeout und $ apply

ich fühle, was ich habe jetzt ein einfach ist, wie ich es bekommen kann, und alles, was ich gelesen habe, sagt dieser

angularjs-load-data-from-service

angular-controller-cant-get-data-from-service

angularjs-promises-not-firing-when-returned-from-a-service

angularjs-promise-not-resolving-properly arbeiten sollten

angularjs-promise

Diese Links waren nur von heute.

Ich dachte, es könnte ein $ scope Problem sein, da ich in der Vergangenheit keine Daten bekommen $ Bereiche gesehen haben, wenn mehrere Controller zu gewöhnen, aber die Seite einfach einen Controller in index.html als <body ng-app="myApp" ng-controller="BodyCtrl"> Einrichtung erklärt. Die wichtigsten app.js nutzt Staaten (von ui-Router glaube ich) wie so ...

.state('app.view', { 
    url: '/view', 
    templateUrl: 'views/view.tpl.html', 
    controller: 'MyCtrl' 
    }) 

befestigen Controller zu den verschiedenen Seiten. Außerdem hat die Seite ein paar andere Controller, die Daten von Diensten bekommen, die ich zuerst als Vorlage durchgesehen habe, aber die Daten und die Ergebnisse sind dort viel komplizierter als das, was ich versuche zu bekommen. Unterm Strich greifen die Controller jedoch auf Daten zu, die von Services bereitgestellt werden. Sie benutzen alle $ resource, und so habe ich mit diesem Problem angefangen. Ich habe mit $ http stecken, weil es sollte arbeiten, und ich möchte, dass die Arbeit damit, bevor ich auf etwas 'höheres Niveau' bewegen. Außerdem muss ich nur von den Endpunkten kommen, also war $ ressource übertrieben.

Service

.factory('MyService', ['$http', '$q', '$rootScope', function ($http, $q, $rootScope) { 
    var defer = $q.defer(); 
    var factory = {}; 
    factory.all = function() { 
     $http({method: 'GET', url: 'http://URLtoJSONEndpoint'}). 
      success(function (data, status, headers, config) { 
       console.log('data success', data); 
       defer.resolve(data); 
      }). 
      error(function (data, status, headers, config) { 
       console.log('data error'); 
       defer.reject(data); 
      }); 

     return defer.promise; 
    }; 
    return factory; 
}]); 

Controller

.controller('MyCtrl', ['$scope', '$state', '$stateParams', '$rootScope', 'MyService', '$q', function ($scope, $state, $stateParams, $rootScope, MyService, $q) { 
... 
... 
$scope.data = null; 
$scope.object = MyService; 
$scope.promise = MyService.all(); 

MyService.all().then(function (data) { 
    $scope.data = data; 
    console.log("data in promise", $scope.data); 
}) 
console.log("data", $scope.data); 
console.log("object", $scope.object); 
console.log("promise", $scope.promise); 

$http({method: 'GET', url: 'http://URL'}). 
     success(function (data, status, headers, config) { 
      $scope.data = data; 
      console.log('data success in ctrl', data); 
     }). 
     error(function (data, status, headers, config) { 
      console.log('data error'); 
     }); 

    console.log("data after ctrl", $scope.data); 


    angular.forEach($scope.data, function (item) { 
     // stuff that I need $scope.data for 
    } 

Konsolprotokoll

Das ist also mein Konsolenprotokoll, und ich kann bei so muc bekommen h, nur nicht die eigentlichen Daten!Was ich brauche. Ich wurde sogar verrückt und erweiterte meine .then(function (data) {, um alle Funktionen in der Steuerung zu erfassen, die $scope.data benötigen. Das war ein Zugunglück.

***data null*** 
object Object {all: function} 
promise Object {then: function, catch: function, finally: function} 
***data success after ctrl null*** 
data success in ctrl Array[143] 
data success Array[143] 
data in promise Array[143] 
data success Array[143] 

Soweit ich sagen kann, diese sollte Arbeit, aber ich bin nicht sicher, wo sonst kann das Problem sein! Vielleicht verstehe ich nicht, wie Versprechen funktionieren oder lösen. Ich habe Angular vorher mit einem anderen Projekt benutzt, aber ich war dort, als ich anfing und verstand, wie es zusammengesetzt wurde. Dieses Projekt war anders strukturiert und fühlt sich viel chaotischer an. Ich würde es gerne vereinfachen, aber ich kann nicht einmal einige einfache Daten zurückgeben!

Ich freue mich über jede Hilfe/Feedback Sie bei der Identifizierung, warum dies nicht funktioniert, danke!

EDIT: Also ist die Frage, warum ist console.log("data", $scope.data) zurück Null/vor dem Versprechen?

etwas weiter unten in der Steuerung Ich habe diese

angular.forEach($scope.data, function (item) { 
// stuff 
} 

und es scheint nicht, den Zugriff auf die Daten zu haben.

EDIT2: Ich habe die $http.get habe ich in der Steuerung wurde mit, zusammen mit den Konsolenprotokollen für sie und die tatsächlich forEach Ich brauche $scope.data für

EDIT3:

aktualisiert Dienst

.service('MyService', ['$http', function ($http) { 
    function all() { 
     return $http({ 
      url: 'http://URL', 
      method: 'GET' 
     }); 
    } 

    return { 
     all: all 
    } 
}]); 

aktualisierte Steuerung

MyService.all().success(function (data) { 
     $scope.data = data; 

     angular.forEach($scope.data, function (item) { 

      // Turn date value into timestamp, which is needed by NVD3 for mapping dates 
      var visitDate = new Date(item.testDate).getTime(); 

      switch (item.Class) { 
       case "TEST": 
        testData.push(
         [ 
          visitDate, 
          item.Total 
         ] 
        ); 

      } 

     }); 

     console.log("test Data in success", testData); 
    }); 


$scope.testData = [ 
     { 
      "key": "Test", 
      "values": testData 
     } 
    ]; 

Also $scope.testData muss in der Ansicht (nvd3 Diagramm) verwendet werden, und es erhält nicht die Daten.

SOLUTION

MyService.all().success(function (data) { 
     $scope.data = data; 

     angular.forEach($scope.data, function (item) { 

      // Turn date value into timestamp, which is needed by NVD3 for mapping dates 
      var visitDate = new Date(item.testDate).getTime(); 

      switch (item.Class) { 
       case "TEST": 
        testData.push(
         [ 
          visitDate, 
          item.Total 
         ] 
        ); 
      } 

     }); 

     console.log("test Data in success", testData); 

     $scope.testData = [ 
     { 
      "key": "Test", 
      "values": testData 
     } 
    ]; 
    }); 
+2

So Ihre Frage ist, warum 'console.log („data“, $ scope.data); // => Daten null'? Wenn ja, liegt das wahrscheinlich daran, dass das Protokoll ausgeführt wird, bevor der asynchrone Aufruf beendet wird.Die zwei Aufrufe von 'MyService.all();' werden zwei Anfragen auslösen. Ich denke, das erste ist nicht notwendig. – Yoshi

+1

Ja, genau! Danke für das Hinzeigen, war nicht sehr klar – mykepwnage

+1

Ich würde beginnen, indem Sie es in Ihrem Controller arbeiten, so auf Erfolg do $ scope.data = Daten; Wenn Sie sehen, dass der Anruf erfolgreich funktioniert, beginnen Sie mit der Weiterleitung von Diensten, denken Sie, dass Sie Komplexität hinzufügen. $ http gibt bereits ein Versprechen zurück, so dass Sie kein anderes Versprechen brauchen. https://docs.angularjs.org/api/ng/service/$http – LightningShield

Antwort

5

Dies könnte ein sehr einfaches Beispiel dafür, wie Ihr Service aussehen könnte:

app.controller('AppCtrl', ['$scope', 'MyService', function ($scope, MyService) { 
    $scope.data = null; 

    MyService.all().success(function (data) { 
    $scope.data = data; 

    // init further handling of `.data` here. 
    }); 
}]); 
:

app.service('MyService', ['$http', function ($http) { 
    function all() { 
    return $http({ 
     url: 'data.json', 
     method: 'GET' 
    }); 
    } 

    return { 
    all: all 
    } 
}]); 

In der Steuerung können Sie es wie so verwenden

Demo: http://plnkr.co/edit/l8pF8Uaa312A8kPtaCNM?p=preview


Zur Beantwortung der Frage, warum die Konsolenprotokolle data null: Dies ist einfach, weil das Protokoll vor den Oberflächen asynchroner Aufruf geschieht.

0

Ich bin mit dem gleichen Problem konfrontiert. Ich lösen dieses Problem, indem $rootScope innerhalb der Versprechen mit, anstatt die $scope.So$rootScope.data wird verfügbar in console.log