Angular REST client ngResource can't get json - javascript

I have simple RESTful server with Flask and I like to make a simple client with AngularJS using ngResource. The idea is make a GET to the server, and obtain a json file.
This is my services.js
var IpZapServices = angular.module('IpZapServices', ['ngResource']);
IpZapServices.factory('Plug', ['$resource', function($resource) {
return $resource('http://localhost:8003/api/plugs/:id',
{id : "#id"}, {
query: {method: 'GET', params: {}, isArray: false}
});
}]);
And the controllers.js
var IpZapControllers = angular.module('IpZapControllers', []);
IpZapControllers.controller('PlugListCtrl', ['$scope', 'Plug', function($scope, Plug) {
$scope.plugs = Plug.query();
console.log($scope.plugs);
}]);
But, I don't get the json file, get this:
Object { $promise: Object, $resolved: false }
Why? What's I do wrong? Thanks!
EDIT:
This is the raw response that I receipt from the server.
{"plugs": [
{"alarm": [],
"id": 0,
"name": "Plug 0",
"state": false},
.
.
.
{"alarm": [],
"id": 3,
"name": "Plug 3",
"state": false}
]}
EDIT 2: Solution
The problem is in the server. Simply add to the server Flask-CORS and work!
from flask.ext.cors import CORS
app = Flask(__name__)
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
The solution is from this question

You need to resolve the promise you have created with Plug.query()
Try this:
Plug.query().$promise.then(function (response) {
console.log(response)
$scope.plugs = response;
});
More information on this can be found in the docs on angularjs.org:
https://docs.angularjs.org/api/ngResource/service/$resource

Try this:
var IpZapControllers = angular.module('IpZapControllers', []);
IpZapControllers.controller('PlugListCtrl', ['$scope', 'Plug', function($scope, Plug) {
$scope.plugs = Plug.query();
$scope.plugs.$promise.then(function (result) {
console.log(result);
$scope.plugs = result;
});
}]);
Explanation:
Your call to query will not return the data immediately. It instead returns a promise object that will eventually get your data once the HTTP request is complete (notice that the console message said resolved: false).
Read More:
Promises in AngularJS, Explained as a Cartoon

It seems that you have a promise there.
Don't assign the return value of the function, you need to wait till the promise resolves or rejects
Try
Plug.query().$promise
.then(function (response) {
// success code here
})
.catch(function (err) {})

Whwn connecting to a webapi from the controller, use the success and error promise from the method call.
Ctrl.$inject = ["$scope", "Service"];
function Ctrl($scope, Service) {
Service.getJson().success(function (data) {
$scope.json = data;
})
.error(function (data) {
// data should show the error
});
}

Related

how to use HttpBackend for the $http

I'm having a hardtime to create a Test with the Controller that uses promise when doing initialization. here's my angularjs scirpt.
Javascript.js
var appModule = angular.module('appModule', []);
appModule.controller('c0001Controller', function($http, $window) {
var user = {};
this.c0001Data = user;
this.submitForm = function() {
if(!angular.isUndefined(this.c0001Data.user_id) && !angular.isUndefined(this.c0001Data.password))
{
var promise = $http.post('C0001Login', user);
promise.success(function(data, status, headers, config) {
if(data.message == 'error'){
alert('Invalid Username/Password');
} else {
$window.location.href = data.url + "#/c0003";
}
});
promise.error(function(data, status, headers, config) {
alert("Invalid Username/Password");
});
}
else {
alert ("Invalid/ Username/password");
}
};
});
Using $httpBackend is more like setting up a fake call to intercept the original call of your $http service in your test cases.
Say you in your controller/service you have an $http get that gets from the request url 'api/employees'. In your test you would like to do something like this before the actual call to your function that calls $http:
$httpBackend.expectGET('api/employees').and.return(200, [
{ id: 1, name: 'sample' },
{ id: 2, name: 'sample 2' }
]);
(JasmineJS) In this way the original $http get request to your url 'api/employees' will not be called instead, the $httpBackend's setup/expected call will be called, and a http status code of 200 along with the array data will be returned.
This would work well on expecting a POST with data parameters. You should always know the request url, the data and other configs used in your original $http calls.
P.S. Always return appropriate HTTP status codes when using $httpBackend. Say, returning an HTTP status code 400 will trigger your catch block in the code you're testing.

Angular Factory getdata

i´m trying to create a factory with angular.js and y have this json structure from the github api:
[
{
"login": "mojombo",
"id": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/1?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/mojombo",
"html_url": "https://github.com/mojombo",
"followers_url": "https://api.github.com/users/mojombo/followers",
"following_url": "https://api.github.com/users/mojombo/following{/other_user}",
"gists_url": "https://api.github.com/users/mojombo/gists{/gist_id}",
"starred_url": "https://api.github.com/users/mojombo/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/mojombo/subscriptions",
"organizations_url": "https://api.github.com/users/mojombo/orgs",
"repos_url": "https://api.github.com/users/mojombo/repos",
"events_url": "https://api.github.com/users/mojombo/events{/privacy}",
"received_events_url": "https://api.github.com/users/mojombo/received_events",
"type": "User",
"site_admin": false
}]
i want to get the data from the url property that contain the info of the user and the idea is get that data from all the user.
this the my code so far from the factory:
angular
.module('app')
.factory('userFactory', function($http){
function getData(){
return $http.get('https://api.github.com/users');
}
function userData(){
getData().success(function(data){
return $http.get('https://api.github.com/users'+ data.url)
}).error()
}
return{
getData : getData
}
});
and this is the controller:
angular
.module('app')
.controller('listUserController', function($scope, userFactory){
$scope.users;
userFactory.getData().success(function(data){
$scope.users = data;
}).error(function(error){
console.log(error);
})
});
but i can get the data, coul you help please.......
Angular encapsulate the api response in an object, try
userFactory.getData().success(function(response){ // response instead of data
$scope.users = response.data; // response.data instead of data
}).error(function(error){
console.log(error);
})
you can try the working plnkr here.
It does:
$resource(user.url)
To request for individual user for its data
result.push(userData)
Push to result and return to controller
userFactory.userData().then(function(data){
vm.userData = data;
});
We're using $resource here because we want to keep the reference to the data in the result array. Then after response come from server, our result array will reflect the changes and show in the view.

Angularjs Ionic JSON object not returning data

I am trying to get data back from a web service, I have to approaches the first is calling the data from the controller which works here is the code
$http({
method: 'POST',
url: 'https://url_json.php',
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset-UTF-8'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: paramsVal
}).then(function(response){
$scope.myData = response.data.PlaceDetailsResponse.results[0].first_name;
console.log('my data',$scope.myData);
});
}
but I would like to share the data between controllers so I read service is the best options, so in my services.js I have:
.factory('userService', function($http){
return {
getUsers: function(){
return $http.post("https://url_json.php",
{entry : 'carlo' ,
type:'first_name',
mySecretCode : 'e8a53543fab6f00ebec85c535e'
}).then(function(response){
users = response;
return users;
});
}
}
})
but when I call it from the controller with var user = userService.getUsers(); returns the below in the console:
user is [object Object]
and inspecting element within chrome I only see:
user is Promise {$$state: Object}
Also in chrome when I drill down on Promise the data value = "".
Can anyone take a look at my services and see if I'm doing anything wrong.
Thanks
.then returns a promise. You're falling for the explicit promise construction antipattern.
getUsers: function(){
return $http.post("https://url_json.php",
{entry : 'carlo' ,
type:'first_name',
mySecretCode : 'e8a53543fab6f00ebec85c535e'
})
}
The above is all you need. Then, in your controller:
userService.getUsers()
.then(function(response) {
$scope.data = response.data; // or whatever
});
I would recommend looking at John Papa AngularJS style guide. He has a lot of information about fetching service data, using it in controllers, etc.
In your controller you will have to assign the user variable by resolving the promise return from the getUsers like below:
$scope.user = [];
$scope.error ="";
userService.getUsers().then(function(data){
$scope.user = data
},function(err){
$scope.error = err;
});
Hope this helps.

AngularJS: Routes with Multiple resolves using Services are not firing

I am configuring an AngularJS app and am having a little trouble ensuring that my promises are firing before the controllers are loading. My understanding is that this can be done. A bit of code:
First, here's the router code:
$routeProvider
.when('/apage', {
controller: 'APageController',
templateUrl: 'app/apage/apage.view.html',
requiresLogin: true,
resolve: {
"data": function($q, data1Service, data2Service) {
var data1 = data1Service.getData();
var data2 = data2Service.getData();
return $q.all({
data1: data1.$promise,
data2: data2.$promise});
}
}
})
...
Here's one of the service functions (both are similar)...
function getData() {
var deferred = $q.defer();
$http(req)
.success(function(data, status, headers, config) {
// store data ...
deferred.resolve(1); // just a flag to say it worked
$rootScope.$apply();
})
.error(function(data, status, headers, config) {
deferred.resolve(0);
$rootScope.$apply();
});
return deferred.promise;
}
And here's the controller code...
angular
.module('app')
.controller('APageController', APageController);
APageController.$inject = [... 'data'];
function APageController(... data) {
var data1 = data.data1;
var data2 = data.data2;
...
All three are in different files but part of the same module. There must be some concept I'm overlooking. Is there anything apparent here to explain why my resolve promises are not firing?
Thank you.
If you pass in object literal to q.all it will resolve immediately. Instead pass array of promises so that it waits for it to resolve reject. Also .$promise is not needed in your case because you are already returning a promise from your service(based on the displayed code). $promise is generally attached by the object returned by $resource
i.e
return $q.all([data1Service.getData(),
data2Service.getData()]);
and expect data to be array of data resolved from above 2 calls.
or create 2 resolves:
resolve: {
"data": function($q, data1Service, data2Service) {
return data1Service.getData();
},
"data2": function($q, data1Service, data2Service) {
return data2Service.getData();
}
}
and inject data and data2.
otherwise, chain through and change the response format to expect the way you were originally trying to get.
resolve: {
"data": function($q, data1Service, data2Service) {
return $q.all([data1Service.getData(),data2Service.getData()])
.then(function(response){
return {
data1:response[0],
data2:response[1]
};
});
}
}
Do not place rootScope.apply inside your service, it will cause digest already in progress error (since angular will ). $http will automatically resolve it.
You just need this.
function getData() {
return $http(req);
}

Angular wp-api cannot get headers for X_Total_Pages

I'm using Angular wp-api module and each time my $resource request responds I can see the ResponseHeaders in Chrome with X_Total_Pages and other header information. But I cannot add them to the scope.
Here is my controller...
.controller('newslettersController', ['$scope','$stateParams','$sce','WPFactory', function ($scope,$stateParams,$sce,WPFactory) {
$scope.newsletters = WPFactory.query({
param1: 'posts',
page: $scope.pageNum,
'filter[cat]': 8,
'filter[posts_per_page]' : 10,
'filter[orderby]': 'ID'
}, function(data, reponseHeaders) {
$scope.header = reponseHeaders('X_Total_Pages');
});
});
}]);
And my factory...
.factory("WPFactory", function($resource) {
var dataResponse = $resource('http://www.example.com/wp-json/:param1/:param2/:param3/:param4/:param6/:param7', {}, {
get: {
method: 'GET'
}
});
return dataResponse;
})
is this jeffsebrings angular module? If it is I think you need to inject your service with wpAPIResource:
.factory("WPFactory", function($resource, wpAPIResource)
and use it to query the json rest api (wp-api).
Also, not sure if your controller is passing the query object quite right:
I would change up your factory something like this:
.factory("WPFactory", function(wpAPIResource) {
var posts_query = function(args) {
return wpAPIResource.query(args);
};
return posts_query;
})

Categories