Returning JSON from a factory to a controller with angularjs

3

I'm starting to study angular deeper, and I'm having trouble processing JSON data in 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 the state to me. Simple, right?

My JSON looks 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 returnsData, which is in the scope of the factory returns the objects coming from JSON by GET, and in my controller, I'm going to get the city, and return in my array of objects which the state relative to capital.

My problems:

1 - What I get in the console.log (vm.dados) 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 array of objects, why is this happening?

2 - With the correct array returned, how will I do this object search? Can underscore help me? I could not find any function to help with this.

    
asked by anonymous 09.09.2015 / 04:34

1 answer

4

First thing, when you make a $ http request, you're working Assynchronously, which means its function.

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

It is Assyncrona, so when you call the returnData, it is returning you the function and not the result of it, to leave the same "Sync" it is necessary to implement a PROMISE, " $q " or a promise of return . 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;
   }

Remembering that when you make a request $ http, passing a configuration JSON its return is a response object with the properties Data, Status, etc.

More in ref. link

The call to this method would look 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 correct array, you need to see what you need to do .. you can fill in a variable and use ng-repeat in a Options of a selectBox to display or play on a grid, it depends on your needs.     

09.09.2015 / 05:23