Angular factory $resource returns no value - json

I have recently downgraded my angular app from 1.3 to 1.2 as the client needs to support IE8.
My factory resource function was working in 1.3 but now the $values array is not seen in the returned JSON response.
Here is what the factory function looks like:
offersController.factory('Offer241GetAll', function ($resource, config) {
return $resource(config.apiUrl + '/TwoForOne/GetAll');
});
And the controller that calls the method:
offersController.controller('offers241Controller', function ($scope, Offer241GetAll) {
Offer241GetAll.get(function (data) {
$scope.offers = data.$values;
});
});
data.$values should contain an array but data only contains:
$promise: Object
$resolved: true
Strangely this $http.get() method works and I have confirmed that values are being sent by the API:
$http.get(config.apiUrl + '/TwoForOne/GetAll').then(function(r){
$scope.offers = r.data.$values;
});
How can I continue to use my resource function like before in version 1.3?
Are there any differences to how this works in different versions of angular?

$http and $resource methods works differently.
$http get method returns a promise.
$resource method Offer241GetAll.get returns to you an object with promise and state of promise.
You can try something like this:
offersController.controller('offers241Controller', function ($scope, Offer241GetAll) {
Offer241GetAll.get().$promise.then(function (data) {
$scope.offers = data;
});
});
More about this you can find here

Related

Consuming JSON string array, returned by a webservice, in AngularJS

There is a Webservice that is returning a json object in below format:
["Brazil","Argentina","Chile"]
(this json object has been parsed by Online JSON parsers, which proves it is a proper json object)
In AngularJS, I wrote the below code to consume the WebService.
app.factory('webServiceFactory', ['$http', function ($http) {
return $http.get('http://SomeWebService/api/anOperation')
.success(function (data) {
return data;
})
.error(function (err) {
return err;
});
}]);
When I call this in my controller, the success part is never hit and, instead, the error part is executed. That means there is some error calling the web-service. I think it has to do something with the JSON object that is being returned.
Edit 1: The Controller code
app.controller('mainController', ['$scope', 'webServiceFactory', function ($scope, webServiceFactory) {
webServiceFactory.success(function (data) {
$scope.Countries = data;
});
}]);
Edit 2: Localhost & CORS
When I hosted the service in my local IIS and consumed it using localhost, it worked. That means there is no error in consuming the JSON String array.
However, when I use a Fully qualified name or machine name, the FireFox indicates CORS header missing 'Access-Control-Allow-Origin'.
This might lead to another question, as to how to make it CORS compatible. However, the main question is closed.
So, my question, is How do I consume a web-service in AngularJS that returns just an array of strings with no Key/Value pair?
Thanks
maybe you are doing a request to a service in other domain; that is not possible since exists the "same origin policy" https://www.w3.org/Security/wiki/Same_Origin_Policy
app.factory('webServiceFactory', ['$http', function ($http) {
return
{
getCountries: function(callback){
$http.get('http://SomeWebService/api/anOperation').then(function(reponse){
callback(response.data);
});
}
};
}]);
Then in your controller
webServiceFactory.getCountries(function(countries){
$scope.countries = countries;
});

Angular service/factory return after getting data

I know this has something to do with using $q and promises, but I've been at it for hours and still can't quite figure out how it's supposed to work with my example.
I have a .json file with the data I want. I have a list of people with id's. I want to have a service or factory I can query with a parameter that'll http.get a json file I have, filter it based on the param, then send it back to my controller.
angular
.module("mainApp")
.controller('personInfoCtrl',['$scope', '$stateParams', 'GetPersonData', function($scope, $stateParams, GetPersonData) {
$scope.personId = $stateParams.id; //this part work great
$scope.fullObject = GetPersonData($stateParams.id);
//I'm having trouble getting ^^^ to work.
//I'm able to do
//GetPersonData($stateParams.id).success(function(data)
// { $scope.fullObject = data; });
//and I can filter it inside of that object, but I want to filter it in the factory/service
}]);
Inside my main.js I have
//angular.module(...
//..a bunch of urlrouterprovider and stateprovider stuff that works
//
}]).service('GetPersonData', ['$http', function($http)
{
return function(id) {
return $http.get('./data/people.json').then(function(res) {
//I know the problem lies in it not 'waiting' for the data to get back
//before it returns an empty json (or empty something or other)
return res.data.filter(function(el) { return el.id == id)
});
}
}]);
The syntax of the filtering and everything works great when it's all in the controller, but I want to use the same code in several controls, so I'm trying to break it out to a service (or factory, I just want the controllers to be 'clean' looking).
I'm really wanting to be able to inject "GetPersonData" to a controller, then call GetPersonData(personId) to get back the json
You seems to be syntax issue in your filter function in the service.
.service('GetPersonData', ['$http', function($http){
return function(id) {
return $http.get('./data/people.json').then( function (res) {
return res.data.filter(function(el) { return el.id == id });
});
}}]);
But regarding the original issue you cannot really access the success property of the $q promise that you are returning from your function because there is no such property exist, It exists only on the promise directly returned by the http function. So you just need to use the then to chain it through in your controller.
GetPersonData($stateParams.id).then(function(data){ $scope.fullObject = data; });
If you were to return return $http.get('./data/people.json') from your service then you will see the http's custom promise methods success and error.

Fetching data from a JSON object (from a given API) in AngulaJS

I have the following code to present data from a link (API) as suggestion for an autocomplete box. Although it is working for one link and not the other. I observed that data format for both are different, modified my code accordingly but it is still not helpful.
.js file:
var plunker= angular.module('plunker', ['ui.bootstrap', 'ngGrid']);
function TypeaheadCtrl($scope, $window, $http, limitToFilter) {
$scope.cities = function (cityName) {
return $http.jsonp("http://mtapi.azurewebsites.net/api/institute").then(function (response) {
return response[0].description;
});
};
}
HTML file:
<input type="text" id="depn" ng-model="formdata.department"
typeahead="suggestion.description for suggestion in cities($viewValue)"
placeholder="department" class="form-control">
If you replace the cities function with this one,
$scope.cities = function (cityName) {
return $http.jsonp("http://gd.geobytes.com/AutoCompleteCity?callback=JSON_CALLBACK &filter=US&q=" + cityName).then(function (response) {
return response.data;
});
};``
Even after I changed my code jsonP request to .get, it is still not working
var plunker= angular.module('plunker', ['ui.bootstrap', 'ngGrid']);
function TypeaheadCtrl($scope, $window, $http, limitToFilter) {
$scope.cities = function (cityName) {
return $http.get("http://mtapi.azurewebsites.net/api/institute").success(function(data) {
return data[0].description;
});
};
}
It is working fine.
Is there a problem with my code, or a back end server issue?
Change your cities function to use the data property of the response in your .then (that's how you'll access the response from a resolved HttpPromise):
var plunker= angular.module('plunker', ['ui.bootstrap', 'ngGrid']);
function TypeaheadCtrl($scope, $window, $http, limitToFilter) {
$scope.cities = function (cityName) {
return $http.get("http://mtapi.azurewebsites.net/api/institute").then(function (response) {
return response.data[0].description;
});
};
EDIT
Even making that code change won't solve your problem. This url does not support cross-origin requests, so you either need to host your angularjs app on the same domain and use a plain $http.get instead of $http.jsonp, or this url needs to support JSONP requests (the content-type of the response from this url is application/json. For JSONP to work it should be application/javascript).
I figured it out lately. Apart from the problem at back end there were issues in this code as well. I was returning the promise, but promise was never resolved to return the value also I was trying to return a string, whereas I should return array of strings. Here's the change:
$scope.aap = result.data;
var res = [];
res.push($scope.aap[0].Description);
return res;

Angularjs $resource and $http synchronous call?

I want write two services one with a $http.get method and one with $resource
This service should receive a Json Object and looks like this, at the moment this code is direct in my controller and not in a service:
var csvPromise= $http.get(base_url + 'DataSource/1').success(function(data) {
$scope.data4=JSON.stringify(data);
});
The problem is, I want save received data in $scope.data4 and I want use this data after the $http.get call but the value is empty.
Direct after this call there is and Object that needs this value:
new myObject($scope.data4)
so myObject must wait so long until the data has arrived.
or can I make a synchronous call with $http or $resource ?
How can i do this ? I have found so many examples with promise and .then but nothing has worked for me.
EDIT: I have now written a service but it didn`t work:
var test=angular.module('myApp.getCSV', ['ngResource']);
test.factory('getCSV',function($log, $http,$q, $resource){
return {
getData: function (id) {
var csvPromise= $http.get(base_url +'DataSource/'+id)
.success(function(data) {
return data;
});
return csvPromise;
}
}
});
and then in my controller I call this:
getCSV.getData(1).then(function(theData){
$scope.data4=JSON.stringify(theData);
new myObject( $scope.data4); });
but this did not work. I thought if the $http.get receives the data then the then Function is called.
I don't believe you can do synchronous calls. That said, you have at least two options:
1) Pass in the data using the $routeProvider resolve feature. From the documentation:
An optional map of dependencies which should be injected into the controller. If any of these dependencies are promises, the router will wait for them all to be resolved or one to be rejected before the controller is instantiated. If all the promises are resolved successfully, the values of the resolved promises are injected
An example on how to use this:
$routeProvider
.when('/your/path', {
templateUrl: '/app/yourtemplate.html',
controller: 'yourController',
resolve: {
data: ['$route', '$http', function($route, $http) {
return $http.get(base_url +'DataSource/1');
}]
}
})
And then in your controller:
app.controller('yourController', ['$scope', 'data', function($scope, data) {
$scope.data4 = JSON.stringufy(data);
var yourObj = new myObject($scope.data4);
}]);
2) The second option is to use promises and only instantiate your new myObject($scope.data4) once the promise successfully completes.
Your code needs to be changed just a bit:
$scope.data4 = '';
var csvPromise= $http.get(base_url +'DataSource/1');
csvPromise.then(function(data){
$scope.data4 = JSON.stringify(data);
}, function(data){
//error handling should go here
window.alert(data);
});
This should give you what it sounds to me like you need.
As i know, there's no way to sync~ call the http or resource. They're hard coded on AngularJS core file :
xhr.open(method, url, true);
And you don't want to hurt your users too by blocking the browser wait the data arrived. You'll better show how you make the nothing has worked for me so we can start working to fix it.
Have you try call new myObject($scope.data4) inside success method?
$http.get(...).success(function(data){
$scope.data4 = JSON.stringify(data); // I've no idea why do you need this.
var stuff = new myObject($scope.data4); // THis is now your.
});

Get JSON data with AngularJS and add methods on the returning object

I need to get some JSON data from the server with Angular. Let's say the user data. I created a service like that:
app.service('User', function($http) {
retrun $http({method: 'GET', url:'/current_user'});
});
And in my controller:
app.controller('SomeCtrl', function($scope, User) {
User.success(function(data) {
$scope.user = data;
});
});
That works just fine but what if I want to add some methods to the user? For instance in the view I would like to do {{user.isAdmin()}}. Is it the correct approach? Where can I add those methods?
If you wanted your service to always return an object with this method, do something like this:
app.service('User', function($http) {
return $http({method: 'GET', url:'/current_user'}).
then(function(response) {
response.data.isAdmin = function() { return true; };
return response.data;
});
});
Now any future code that references this promise and uses .then() will retrieve the new object. Take a look at the promise documentation for more information.
http://docs.angularjs.org/api/ng.$q
Keep in mind by using 'then' on an httpPromise it will be converted to a normal promise. You no longer have the convenience methods 'success' and 'error'.
It may be better practice to create a class for the object you are returning with a constructor function which takes the data object and assigns appropriate properties (or extends the instance). This way you can simply do something like
return new User(val);
And you will get all of the methods you want (with a prototype, etc).
You can do this in a few ways in the service you created:
Start using $resource and use a transform on the response:
http://jsfiddle.net/roadprophet/prtAP/
...
transformResponse: function (data, headers) {
data = {};
data.coolThing = 'BOOM-SHAKA-LAKA';
return data;
}
...
I recommend this method because it scales cleaner due to the use of $resource.
Setup a transformResponse with $http:
http://jsfiddle.net/roadprophet/bPfcz/
Use your own promise that resolves after the get promise resolves but with the mapped data. This is probably the most manual way to handle it since it requires you to manage multiple promises.