Returning JSON from a Factory to a controller with Angularjs

Asked

Viewed 1,172 times

3

I’m starting to study angular more deeply, and am having problems processing JSON data into a Factory and passing them to a controller.

My idea is: A simple app, just for study, where I type the capital and it returns me the state. Simple, no?

My JSON is like this:

[
{ "state": "Rio Grande do Sul", "capital": "Porto Alegre " },
{ "state": "Santa Catarina", "capital": "Florianópolis" },
{ "state": "Paraná", "capital": "Curitiba" },
{ "state": "São Paulo", "capital": "São Paulo" },
{ "state": "Rio de Janeiro", "capital": "Rio de Janeiro" },
{ "state": "Minas Gerais", "capital": "Belo Horizonte" },
{ "state": "Espirito Santo", "capital": "Vitória" } ]

My Factory:

angular.module('appUi')

.factory('CidadeService', ['$http', function($http) {
var vm = this;

var estados = {}

var dados  = [];
var teste = 4;
vm.dados = [];

return { 
    retornaDados : function() { 
        return $http({
            url: '../dados.json',
            method: 'GET'
    })
        .then(function(data) {
        vm.data = data;
        return vm.data;
    })
    }

}
}])

My controller:

.controller('CidadeCtrl', ['$scope','$http','CidadeService', function($scope, $http, CidadeService){

var vm = this;
var enteredcapitalCtrl = null;
vm.enteredcapitalShow = null;
vm.dados = {};

$scope.$watch('enteredcapital', function(enteredcapital) {
        enteredcapitalCtrl = enteredcapital;
});

vm.showState = function() {
    vm.dados = CidadeService.retornaDados();
console.log(vm.dados);
    vm.enteredcapitalShow = enteredcapitalCtrl;
}
}]) 

And my html:

<form action="" ng-submit="cidade.showState()">
    <fieldset>
        <label for="input-cidade" >Digite o nome de uma capital:</label>
        <input type="text" ng-model="enteredcapital">
        <input type="submit" value="Ok">

        <p>O estado é: {{ '''AQUI VIRÁ O ESTADO''' }}</p>
    </fieldset>
</form>

The logic is simple (I think), the function returned, which is in the Scope of Factory returns the objects coming from the JSON by GET, and in my controller, I will take the city, and return in my object array which state relative to capital.

My problems:

1- What I return in the console.log(vm.data) in the controller is as follows:

$$state: Object
status: 1
value: Object
config: Object
data: Array[7]
0: Object
capital: "Porto Alegre "
state: "Rio Grande do Sul"
__proto__: Object
1: Object
2: Object 
3: Object 
4: Object 
5: Object 
6: Object
 length: 7 
__proto__:  
array[0]
headers: (c)
 status: 200 
statusText: "OK"
 __proto__: Object 
__proto__: Object
 __proto__: d

And I should just return the object array, because this is happening?

2- With the correct array returned, how do I search for the objects? Can the underscore help me? I couldn’t find any function to help with that.

1 answer

4


First thing, when you make a request $http, you are working Assyncronamente, which means its function.

retornaDados : function() { 
    return $http({
        url: '../dados.json',
        method: 'GET'
})
    .then(function(data) {
    vm.data = data;
    return vm.data;
})
}

is Assyncrona, just when you call the returnedDados, it is returning you the function and not the result of it, to leave the same "Synchronous" it is necessary to implement a PROMESSE, "$q" or be a return promise. your code would look like this.

   retornaDados : function() { 

        var deffered = $q.defer();
        $http({ url: '../dados.json', method: 'GET'})
          .then(function(response) {
             deffered.resolve(response.data);
          })

        return deffered.promise;
   }

Remember that when you make a request $http, passing a configuration JSON your return is an object (Answer) with the properties Data, Status, etc.

more in ref. https://docs.angularjs.org/api/ng/service/$http

The call for this method would be as follows.

    vm.showState = function() {
        CidadeService.retornaDados().then(function(retorno){
          console.log(retorno); // no retorno você vai ter o que veio do $http

          //vm.enteredcapitalShow = enteredcapitalCtrl;
    });
}

Now with the right array, you need to see what you need to do.. you can fill a variable and use ng-repeat, in a selectBox Options to display or play on a grid, depending on your need.

  • Got it! Very good the explanation, really had not attacked me to these details.Thank you

  • rsrs, no problems, any questions at @Carvbru

Browser other questions tagged

You are not signed in. Login or sign up in order to post.