I am stuck trying to retrieve a single json item from an array to from my $http get.
I have tried using scope, and a few other methods- but none work.
The json object/data appears (in the Chrome network inspector) and my directives in my HTML are correct.
How can I get Angular to understand a give a single item in a json array to a directive?
My object looks like this:
[{"id":1, "name":"test1"}]
function productsApiProvider($http, $stateParams) {
var product_id = $stateParams.product_id;
var getApiData = function () {
return $http.get(BASE_URL + product_id);
};
var BASE_URL = 'http://123.com/api/item/';
return {
getApiData: getApiData
};
}
function ProductsCtrl($scope, $log, productsApi, UserService) {
$scope.product=[];
productsApi.getApiData()
.then(function (result) {
console.log(JSON.stringify(result.data)) //Shows log of API data
$scope.products.unshift(result.data);
})
.catch(function (err) {
$log.error(err);
});
}
It should be
$scope.product.unshift
not
$scope.products.unshift
notice the "s" at the end of product.
Adding as answer from comments so it can be accepted, closing this out.
result.data[0].name value "test1" is that what you need here for the object result.data[0]
Related
I'm pulling in an array from an API, like so:
// in Service....
return $http.get(
'http://api.com/team/16110?Authorization=565eaa22251f932b9f000001d50aaf0b55c7477c5ffcdbaf113ebbda'
)
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
This works fine, but only for the one array of data that the URL calls. I want to be able to call in other specific arrays by adapting one part of the URL - 16110.
I want to be able to use a property from a separate property elsewhere within this $http call. I tried this:
'http://api.com/team/' + $scope.thisId +'?Authorization=565eaa22251f932b9f000001d50aaf0b55c7477c5ffcdbaf113ebbda'
But this just broke the Service.
Is there a relatively simple solution to this? I feel like I'm really close, but can't crack it.
UPDATE - the following solution works...
1. SERVICE
app.factory('DataService', ['$http', function($http) {
return {
getTeamDetailsById: function(teamId) {
return $http.get('http://api.com/team/' + teamId + '?Authorization=xxxxxx'
)
}
}]);
2. CONTROLLER
app.controller('NationsController', [
'$scope',
'DataService',
NationsController]);
function NationsController($scope, DataService) {
self = this;
DataService.getTeamDetailsById($scope.whichTeam).then(
function(response) {
//success callback
$scope.teamDetails = response.data;
},
function(response) {
//an error has occurred
});
}
3. response.data
I am expecting to get back an object from this. The API URL is fine, I've tried it directly and it returns the data ok.
Pass the id from the scope into the service:
app.factory("DataService", ["$http", function($http) {
return {
getTeamDetailsById: function(teamId) {
return $http.get('path/to/api' + teamId + '?Auth=xxxx')
}
};
}]);
Call it from the controller:
DataService.getTeamDetailsById($scope.teamId).then(function(response) {
//success callback
$scope.teamDetails = response.data;
}, function(response) {
//an error has occurred
});
This:
'http://api.com/team/' + '$scope.thisId' +'?Authorization=565eaa22251f932b9f000001d50aaf0b55c7477c5ffcdbaf113ebbda'
is equal to http://api.com/team/$scope.thisId?Authorization=[...], which is not what you want. Remove the quotes around $scope.thisID, like this:
'http://api.com/team/' + $scope.thisId +'?Authorization=565eaa22251f932b9f000001d50aaf0b55c7477c5ffcdbaf113ebbda'
This will work assuming you've set $scope.thisId to whatever resource's ID you want to fetch.
hey guys, i have problem with get id. now i cant get '_id' from service.
this is my service
application.service('Arrears', [
function()
{
var db = new PouchDB('localhost:5984/arrears');
return {
get: function (_id) {
return db.get(_id)
.then(function (object) {
return db.remove(object)
.catch(function (err) {
console.log('error: ' + err); // isn't executed
});
})
.catch(function (err) {
console.log('error: ' + err); // isn't executed
});
},
}
}
]);
for insert data is ok.
now, this is my controller.
application.controller('ArrearsManagementAllController', ['$location', '$mdSidenav', '$scope', 'Arrears',
function($location, $mdSidenav, $scope, Arrears)
{
$scope.id = Arrears.get();
}
]);
and the last is my template.
<md-list-item
md-virtual-repeat="i in items"
ng-click="read(id)">
when i click read, my link show like this
localhost:8080/arrears_management/all/read/undefined
my code can't read the id.
please solve my problems. because im new using angularjs and pouchdb.
now the console show error like this :-
GET localhost/arrears/_id?_nonce=1447904157421 404 (Object Not Found)
wrong things with your code:
1.
get: function (_id) {
var id = get('_id')
},
does not return anything, and
2. get is calling a get method which is not defined
3. you don't have _id anywhere to return it. Maybe you want to put it in a service variable after you get it from the database?
OR, you probably wanted to do this:
get: function (_id) {
var id = db.get('_id');
return id;
},
note the db.get instead of just get and the very useful return. This may depend on the database engine, though...
EDIT
even in the controller you have a big issue: $scope.id = Arrears.get does a more complicated thing that you wish. You just need to replace it with:
$scope.id = Arrears.get();
in order to get the value of id because you were not calling the get method...
On the code below, I am trying to reference the photos array in the appService service from the pictureCtrl controller, but it won't work well. The only thing that works is $scope.photoService referencing appService when I try to call the model on the HTML. When I try to call currentPhoto model on the HTML it won't show anything.
I would like to get the currentPhoto model on the HTML page referencing the first index of the photos array which will be an object and when I click on the favorite button on HTML it will run the sendFeedback method and will change currentphoto. How can do it?
.controller('pictureCtrl', function ($scope, appService) {
// angular.extend($scope, appService);
$scope.photoService = appService;
$scope.photos = appService.photos;
$scope.currentPhoto = appService.photos[0];
$scope.sendFeedback = function (bool) {
if(bool) {}//add it to favorite
var randomIndex = Math.round(Math.random() * flickrData.photos.length-1);
$scope.currentPhoto = angular.copy($scope.service.flickrData.photos[randomIndex]);
};
})
.factory('appService', function ($http) {
var photoService = {};
photoService.photos = [];
photoService.feelingText = "";
photoService.getFlickrPictures = function (text) {
console.log('this has been called');
return $http({
method: "JSONP",
url: apiUrl+'&text='+text+'&format=json&jsoncallback=JSON_CALLBACK'
}).then(function (data) {
photoService.photos = data.data.photos.photo;
console.log('flickrData', photoService.photos);
}, function(err){
throw err;
});
};
return photoService;
}
It seems that the photos array never has been populated. Since you are using a factory, the thing that will get injected into your controller will be a fresh instance of photoService.
You will only see photos if you first call your function to fetch the data from the $http service.
I would create a function loadPhotos on your service that would return the data as a promise to your controller.
I have trouble fetching one unique item from my firebase using angularfire 1.0.0. To clarify, I want my app to fetch a post given a unique firebase id e.g. "-JkZwz-tyYoRLoRqlI_I". It works when navigating in the app e.g. clicking on a link to a specific post, but not on a refresh. My guess is that it has something to do with synchronization. Right now it works when fetching all posts and use it in a ng-repeat. This is a clue to why it works for one item when navigating to the page. This should probably not be hard since this should be a pretty standard operation, but i can't get it to work. I have searched everywhere but there is actually no guide on this. In the API they refer to $getRecord(key)
Returns the record from the array for the given key. If the key is not
found, returns null. This method utilizes $indexFor(key) to find the
appropriate record.
But this is not working as expected. Or am i missing something?
It works for ng-repeat like this:
<div ng-repeat="postt in posts">
<div>
<h1>{{postt.title}}</h1>
<div>{{postt.timestamp}}</div>
<div>{{postt.content}}</div>
</div>
</div>
But not for unique items like this:
<div>
<h1>{{post.title}}</h1>
<div>{{post.timestamp}}</div>
<div>{{post.content}}</div>
</div>
This is the service:
'use strict';
angular.module('app.module.blog.post')
.factory("PostService", ["$firebaseArray", "FIREBASE_URL", function($firebaseArray, FIREBASE_URL) {
var ref = new Firebase(FIREBASE_URL + "posts");
var posts = $firebaseArray(ref);
return {
all: posts, // ng-repeat on this works fine
last: function(nr) {
var query = ref.orderByChild("timestamp").limitToLast(nr);
return $firebaseArray(query); // ng-repeat on this work fine to
},
create: function (post) {
return posts.$add(post);
},
get: function (postId) {
console.log(postId); // This is -JkZwz-tyYoRLoRqlI_I
var post = posts.$getRecord(postId);
console.log(post); // This print null
return post;
},
delete: function (post) {
return posts.$remove(post);
}
};
}]);
As the comments say in the get function, the postId is there and posts is also set, but the post is null.
This is the controller
'use strict';
angular.module('app.module.blog.post', [])
.controller('PostCtrl', ['$scope', '$routeParams', 'PostService', function($scope, $routeParams, PostService) {
// This returns e.g. postId "-JkZwz-tyYoRLoRqlI_I"
console.log($routeParams.postId);
$scope.post = PostService.get($routeParams.postId);
$scope.posts = PostService.all; // Illustrates the example not actually in this controller otherwise
}]);
This is what is an example on what is in the firebase database
<myfirebase>
posts
-JkUnVsGnCqbAxbMailo
comments
content: ...
timestamp: ...
title: ...
-JkZwz-tyYoRLoRqlI_I
comments
content: ...
timestamp: ...
title: ...
-JkhaEf9tQy06cOF03Ts
content: ...
timestamp: ...
title: ...
I find this problem very wierd since it should be very standard. I am obviously missing something, but can't work it out. Any help is very much appreciated!
Thanks in advance!
I know that the documentation of the $getRecord() function is kind of misleading. What you actually get from $firebaseArray is a promise of an array. It means that your posts variable will contain your posts at some point in the future. That being said, it seems that the $getRecord function only works when the promise have been resolved, i.e. when the array has been downloaded from Firebase. To make sure that the promise is resolved when you call the $getRecord function, you can use $loaded() on the promise :
var posts = $firebaseArray(ref);
posts.$loaded().then(function(x) {
var post = x.$getRecord(postId);
console.log(post);
}).catch(function(error) {
console.log("Error:", error);
});
If you are wondering why it works for ng-repeat, it's because Angular knows that the posts variable is a promise and waits for it to be resolved before rendering the values.
This is happening due to promises.
Along the lines of what Kato, Jean-Philippe said, $firebaseArray is not immediately available as it needs to be downloaded.
See the .$loaded() documentation:
.$loaded() "returns a promise which is resolved when the initial array data has been downloaded from Firebase. The promise resolves to the $firebaseArray itself."
That answers your question, and I just wanted to show another way of doing it:
This is a great use case for extending AngularFire services.
As the AngularFire API Documentation says:
"There are several powerful techniques for transforming the data downloaded and saved by $firebaseArray and $firebaseObject. These techniques should only be attempted by advanced Angular users who know their way around the code."
Putting all that together, you accomplish what you want to do by:
Extending the Firebase service $firebaseArray
Following the documentation for extending services.
Example
Here is a working JSFIDDLE example I put together that is tied to one of my public Firebase instances.
It's important to note that you should add ".indexOn":"timestamp" to your rules for /posts.
Factories
app.factory('PostsArray', function (FBURL, PostsArrayFactory) {
return function (limitToLast) {
if (!limitToLast) {
console.error("Need limitToLast");
return null;
}
var postsRef = new Firebase(FBURL + '/posts').orderByChild('timestamp').limitToLast(limitToLast);
return new PostsArrayFactory(postsRef);
}
});
app.factory('PostsArrayFactory', function ($q, $firebaseArray) {
return $firebaseArray.$extend({
getPost: function (postKey) {
var deferred = $q.defer();
var post = this.$getRecord(postKey);
if (post) {
console.log("Got post", post);
deferred.resolve(post);
} else {
deferred.reject("Post with key:" + postKey + " not found.");
}
return deferred.promise;
},
createPost: function (post) {
var deferred = $q.defer();
post.timestamp = Firebase.ServerValue.TIMESTAMP;
this.$add(post).then(function (ref) {
var id = ref.key();
console.log("added post with id", id, "post:", post);
deferred.resolve(ref);
}).
catch (function (error) {
deferred.reject(error);
});
return deferred.promise;
}
});
});
Controller
app.controller("SampleController", function ($scope, PostsArray) {
var posts = new PostsArray(5);
$scope.posts = posts;
$scope.newPost = {};
$scope.createNewPost = function () {
posts.createPost($scope.newPost);
}
$scope.postId = '';
$scope.getPost = function () {
posts.getPost($scope.postId).then(function (post) {
$scope.gotPost = post;
}).
catch (function (error) {
$scope.gotPost = error;
});
}
});
I have a problem with outputting the values of a promise function.
$scope.getTeacher = function(teacherAbr) {
var promise = dataService.getTeacher(teacherAbr);
var testje = promise.then(function(payload) {
return payload;
});
return testje; // outputs an d object, not the direct payload values
};
The output of this controller function is this:
However, when I'm doing testje.$$state it returns undefined. How can I output the value object? I can't output the payload variable in a new $scope, because this data is dynamic.
Here is a simplified version of this on Plunker.
You should change the way you think about things when you work with asynchronous code. You no longer return values, instead you use Promise or callback patterns to invoke code when data becomes available.
In your case your factory can be:
.factory('dataService', function($http, $log, $q) {
return {
getTeacher: function(teacher) {
// Originally this was a jsonp request ('/teacher/' + teacher)
return $http.get('http://echo.jsontest.com/key/value/one/two').then(function(response) {
return response.data;
}, function() {
$log.error(msg, code);
})
}
};
});
And usage in controller:
dataService.getTeacher('Lanc').then(function(data) {
$scope.teacher = data;
});
Also $http.get already returns promise, so you don't have to create one more with $q.defer().
Demo: http://plnkr.co/edit/FNYmZg9NJR7GpjgKkWd6?p=preview
UPD
Here is another effort for combining lessons with teachers.
Demo: http://plnkr.co/edit/SXT5QaiZuiQGZe2Z6pb4?p=preview
//in your services file
return {
getTeacher: function (teacher) {
// Originally this was a jsonp request ('/teacher/' + teacher)
return $http.get('http://echo.jsontest.com/key/value/one/two')
})
//change the controller to this
dataService.getTeacher(teacherAbr).then(function(msg){
$scope.getdata=msg.data;
console.log("From server"+msg.data);
});