I have been pulling my hair out here. I am using ion-autocomplete and want to pull data with a factory.
My Factory ...
myApp.factory('items', function($http){
return {
list: function(query,callback){
$http.get('http://192.168.100.100/myApp/products/' + query).success(callback)
}
};
});
To get the data I use ..
items.list(function(items) {
$scope.items = items;
});
The demo for autocomplete request data like ..
$scope.getTestItems = function (query) {
return {
items: [
{id: "1", name: query + "1", view: "view: " + query + "1"},
{id: "2", name: query + "2", view: "view: " + query + "2"},
{id: "3", name: query + "3", view: "view: " + query + "3"}]
};
};
So I figure this is a workable solution ..
$scope.getTestItems = items.list(query,function(items)
{
console.log(items);
return items;
}
)
but clearly is not. I have tried ..
$scope.getTestItems = function(query)
{
items.list(query,function(items)
{
console.log(items);
return items;
}
)
}
Which does give me a console of the result but this is not returned to getTestItems
According to the docs (assuming I've got the right lib here), you can return a promise
myApp.factory('items', function($http){
return {
list: function(query) {
return $http.get(... + query).then(function(res) {
return res.data; // unwrap the response data
// see the "Returns" section at https://docs.angularjs.org/api/ng/service/$http#usage
});
}
};
});
and the controller
$scope.getTestItems = function(query) {
return items.list(query);
};
How about this
Factory
list: function(query,callback){
return $http.get('http://192.168.100.100/myApp/products/' + query)
}
In this way you are returning the promise from the factory.
Controller
$scope.getTestItems = function(query){
items.list(query).then(function(items){
console.log(items);
});
}
The callback will execute as soon as the promise resolves.
you could try this,
myApp.factory('items', function($http){
return {
list: function(query){
return $http.get('http://192.168.100.100/myApp/products/'+query);
}
};
});
then in your controller
var promise = items.list(query);
promise.then(function(response){
//here we go
$scope.items = angular.fromJson(JSON.parse(response.data));
});
Related
This is my first time when I try to return data from promise inside JSON object and I stuck with this task
So common way is something like this
service js
app.factory("dataService", ["$http",
function ($http) {
function getData(id) {
return $http.get('endpoint', id)
.then(function (response) {
return response.data
});
}
return {
getData: getData
}
}])
controller js
$scope.data = {}
dataService.getData($routeParams.id)
.then (function (res) {
$scope.data = res
});
this works fine and everybody is happy
now I'm trying to assign data inside object
controller js
angular.forEach($scope.properties, function (item) {
$scope.data.properties.push({
order: item.number,
name: item.name,
value: item.value,
items: $scope.getProp(item.id)
})
});
$scope.getProp = function (id) {
return dataService.single(id)
.then (function (res) {return res});
};
service js
function single(id) {
return $http.get('endpoint' + "/" + id)
.then(function (response) {
return response.data
})
}
and now I'm getting JSON object with promise and $$state inside
I understand the nature of this problem but solution for this problem is out of range of my knowledges, so could somebody help me deal with it ?
One way to make it work is:
$scope.data.properties = [];
var promiseList = $scope.properties.map(function(item) {
var promise = $scope.getProp(item.id);
return promise.then(function (data) {
var newItem = {
id: item.id,
order: item.number,
name: item.name,
value: item.value,
items: data
};
$scope.data.properties.push(newItem);
return newItem;
});
});
$q.all(promiseList).then(function(itemList) {
console.log(itemList);
//More code here
});
The above example creates a list of promises that return objects that have the items property populated with data from the promise returned from $scope.getProps.
In addition it pushes each populated item to scope. Because the asynchronous XHRs may not complete in the order that they were started, the scope list may not be in the same order as the original.
The $q.all method however will wait for all the XHRs to complete and return the list in the original order.
I've created a basic AngularJS app that consumes Yelp's API and am having trouble using $httpProvider.interceptors to parse my response.
Here is my app:
var app = angular.module("restaurantList", []);
My yelpAPI service (not pictured) authenticates my API request and generates a HTTP request. I then output the data received to the Web Console like so:
app.controller("mainCtrl", ["$scope", "yelpAPI", function ($scope, yelpAPI) {
$scope.restaurants = [];
yelpAPI.get(function (data) {
$scope.restaurant = data;
console.log($scope.restaurant);
});
}]);
Here is data from my request:
Object {region: Object, total: 37, businesses: Array[20]}
I want the array located in the businesses property. So, I figured it would be a good idea to use $httpProvider.interceptors to parse the objects found, in the Object.businesses array.
Here is what $httpProvider.interceptors looked like, when I made my initial request:
app.config(function ($httpProvider) {
$httpProvider.interceptors.push(function () {
return {
response: function (response) {
return response;
}
}
});
});
Here is what $httpProvider.interceptors looks like now:
app.config(function($httpProvider) {
$httpProvider.interceptors.push(function() {
return {
response: function(response) {
var old_response = response.businesses,
new_response = [];
for (var i = 0; i < old_response.length; i++) {
var obj = old_response[i],
new_obj = {
restaurant_name: obj.name,
phone_number: obj.display_phone,
yelp_rating: obj.rating,
reservation_url: obj.reservation_url
};
new_response.push(new_obj);
}
return new_response;
}
}
});
});
Now, I'm receiving an error that says TypeError: Cannot read property 'businesses' of undefined. Is there something I'm overlooking?
EDIT #1
I used console.log(response) inside the interceptor to print my response and found that response.businesses should actually be response.data.businesses. Which resolves my error but now my $http call returns undefined. Any idea what my new problem could be?
EDIT #2
app.factory("yelpAPI", function($http, nounce) {
return {
get: function(callback) {
var method = "GET",
url = "http://api.yelp.com/v2/search";
var params = {
callback: "angular.callbacks._0",
oauth_consumer_key: "my_oauth_consumer_key",
oauth_token: "my_oauth_token",
oauth_signature_method: "HMAC-SHA1",
oauth_timestamp: new Date().getTime(),
oauth_nonce: nounce.generate(),
term: "American",
sort: 2,
limit: 20,
radius_filter: 4000,
deals_filter: true,
actionlinks: true
};
var consumerSecret = "my_consumer_secret",
tokenSecret = "my_token_secret",
signature = oauthSignature.generate(method, url, params, consumerSecret, tokenSecret, {
encodeSignature: false
});
params["oauth_signature"] = signature;
$http.jsonp(url, {
params: params
}).success(callback);
}
}
});
In return angular wait object with {data : }:
app.config(function($httpProvider) {
$httpProvider.interceptors.push(function() {
return {
response: function(res) {
var old_response = res.businesses,
new_response = [];
for (var i = 0; i < old_response.length; i++) {
var obj = old_response[i],
new_obj = {
restaurant_name: obj.name,
phone_number: obj.display_phone,
yelp_rating: obj.rating,
reservation_url: obj.reservation_url
};
new_response.push(new_obj);
}
return {data : new_response};
}
}
});
});
Return as {data : new_response}
Emir helped me resolve this issue but essentially, whenever you use $httpProvider.interceptors you have to update response.data and return the entire response object (i.e. not just a new array, as I did) because $http selects the data property for you.
I want the data in res passed to my notes variable. But it's returning a bigger nested object. Why is it happening?
If I inspect in the console the value of cleanArrayOfNotes I get the object that I want, but once its assigned to notes it becomes a quite bigger object. I understand it's part of the nature of the Promises, which at the moment I still trying to understand. Any help?
notes_service.js
var notesService = {notesObjectInService: [], newNote: null};
notesService.getAll = function() {
return $http.get('/notes.json').success(function(data){
//console.log(data)
angular.copy(data, notesService.notesObjectInService);
//console.log(notesService)
})
};
navCtrl.js
var notes = notesService.getAll().then(function(res){
var cleanArrayOfNotes = res.data;
//navCtrl line12
console.log(cleanArrayOfNotes);
return cleanArrayOfNotes;
});
//navCtrl line16
console.log(notes);
This should work for you:
notes_service.js
app.factory ('NoteService', function($http) {
return {
getAll: function() {
return $http.get('/notes.json').then(function(response) {
return response.data;
});
}
}
});
navCtrl.js
NotesService.getAll().then(function(res){
$scope.cleanArrayOfNotes = res.data;
});
Or, if you want to return the result rather than the promise, you can:
notes_service.js
app.factory ('NoteService', function($http) {
var notes = [];
var promise = $http.get('/notes.json').then(function(response) {
angular.copy(response.data, notes);
return notes;
});
return {
getAll: function() {
return notes;
},
promise: promise
}
});
navCtrl.js
// get array of notes
scope.cleanArrayOfNotes = NotesService.getAll();
// or use promise
NoteService.promise.then(function(response) {
scope.cleanArrayOfNotes = response.data;
});
I'm trying to get a Rest array and then display it on my HTML.
the problem that I'm facing is that In My factory I'm able to get the array and display it's content, but not in my controller where I'm always getting the Undefined var. here is my Factory
.factory('coursesService', function($resource) {
var service = {};
service.getAllCouses = function (){
var Courses = $resource("/myproject/rest/training/trainings");
var data = Courses.query().$promise.then(function(data)
{
service.data= data;
console.log("ligne 1: ", service.data[0].name);
console.log("ligne 1: ", service.data[0].creator);
console.log("ligne 2: ", data[1].name);
console.log("ligne 2: ", data[1].creator);
return service.data;
});
}
return service;
})
and my controller
.controller("CoursesController",
function CoursesController($scope, coursesService) {
var courses = {};
courses = coursesService.getAllCouses();
console.log("courses: ", courses);
})
as results I'm getting this:
courses: undefined
ligne 1: Angular
ligne 1: Object {id: "1", username: "User1", email: "user1#gmail.com", password: "password", userProfile: Object}
ligne 2: JavaScript
ligne 2: Object {id: "1", username: "User1", email: "user1#gmail.com", password: "password", userProfile: Object}
Why I'm getting courses: undefined? and Shouldn't be displayed after the list that I'm displaying in the factory?
Your getAllCouses function never returns anything, and so calling it always results in undefined. The callback to the query promise then handler returns something, but not getAllCouses.
You'll need to have getAllCouses return the promise, and then use the result from within a then handler on that promise. You can't just use its return value directly, not if Courses.query() is async (and if it isn't, why is it returning a promise?).
That would look something like this:
.factory('coursesService', function($resource) {
var service = {};
service.getAllCouses = function (){
var Courses = $resource("/myproject/rest/training/trainings");
var data = Courses.query().$promise.then(function(data) {
service.data= data;
console.log("ligne 1: ", service.data[0].name);
console.log("ligne 1: ", service.data[0].creator);
console.log("ligne 2: ", data[1].name);
console.log("ligne 2: ", data[1].creator);
return service.data;
});
return data; // <=== Return the promise (`data` is a bit of a suspect name)
};
return service;
})
Then:
.controller("CoursesController", function CoursesController($scope, coursesService) {
coursesService.getAllCouses().then(function(courses) { // <=== Use the promise
console.log("courses: ", courses); // <===
}); // <===
})
...but I'm not an Angular guy.
getAllCouses() does not return a value, it just sets two local variables, Courses and data.
The Courses.query promise only resolves once the web request is complete, so those logs are delayed.
I fixed the issue by updating my service and controller like this:
.factory('coursesService', function($resource) {
return $resource("/myproject/rest/training/trainings", {
query : {
method : "GET",
isArray : true
}
});
});
I just added the
isArray : true
and i updated the controller
.controller(
"CoursesController",
function UserController($scope, coursesService) {
coursesService.query(function(data) {
console.info("data: ", data)
console.log("1st course: ", data[0].name)
$scope.Courses = data;
});
I fix it simply in this way:
.factory('coursesService', function($resource) {
return $resource("/myproject/rest/training/trainings")
})
and the controller:
.controller("coursesController", function($scope, coursesService) {
coursesService.query(function(data) {
$scope.Courses = data;
});
})
I was trying to reduce my promise objects in my service. I have something like
angular.module('myApp').service('testService', ['Employees','$q',
function(Employees, $q) {
var service = {};
var firstEmp;
var deferred = $q.defer();
Employees.query({
Id: 123
}, function(objects) {
firstEmp = objects[0];
deferred.resolve(objects);
})
service.getFirstEmployee = function() {
var deferredtwo = $q.defer();
// return deferredtwo.promise;
//How to solve the double promise defer in my case
//First promise is wait for the whole employees
//this one is to return first employee
deferred.promise.then(function(){
deferredtwo.resolve(firstEmp);
})
return deferredtwo.promise;
}
return service;
]);
Controller
testService.getFirstEmployee.then(function(firstEmployee){
console.log(firstEmployee) <---show first employee
})
I am not sure how to resolve the double promise objects. Can anyone help me? Thanks a lot!
If your ultimate objective is just to get the first employee, then you don't need all this "double promise" stuff at all. Just resolve one promise with the first employee:
angular.module('myApp').service('testService', ['Employees','$q',
function(Employees, $q) {
var pFirstEmployee = $q(function (resolve) {
Employees.query({ Id: 123 }, function(objects) {
resolve(objects[0]);
});
});
return {
getFirstEmployee: function() {
return pFirstEmployee;
}
};
}
]);
If you want two methods - one that returns a promise for all employees returned from the query, and another that returns just the first one from that set, just create a promise for all the employees and chain off of that:
angular.module('myApp').service('testService', ['Employees','$q',
function(Employees, $q) {
var pAllEmployees = $q(function (resolve) {
Employees.query({ Id: 123 }, resolve);
}),
pFirstEmployee = pAllEmployees.then(function (employees) {
return employees[0];
});
return {
getAllEmployees: function() {
return pAllEmployees;
},
getFirstEmployee: function() {
return pFirstEmployee;
}
};
}
]);
After the clarification I guess this is what you want:
angular.module('myApp').service('testService', ['Employees','$q',
function(Employees, $q) {
var service = {};
var deferred = $q.defer();
Employees.query({Id: 123}, function(objects) {
firstEmp = objects[0];
deferred.resolve(objects);
});
service.getFirstEmployee = function() {
return deferred.promise.then(function(employees){
return employees[0];
});
}
return service;
]);