What is the right way to add more data in to an existing collection with Restanglar?
Currently on page load I am performing:
app.factory('Post', ['Restangular', function(Restangular) {
return Restangular.service('posts');
}]);
var Posts = Post.getList({embed:'comments.replies,tags', limit:'50'}).$object;
$scope.posts = Posts;
This gets my initial bunch of posts nicely.
On the front end the user can then select a tag which filters the results, and I want to load up some more from the server for the specific tag. Currently I am replacing the existing posts with:
Posts = Post.getList({embed:'comments.replies,tags', limit:'100', tag:tag.name}).$object;
$scope.posts = Posts;
The data is coming back great from the API. What is the best practice way to push the data in to the exiting/original Restangular collection?
Ideally I want to keep adding to this collection, merging the result so that there are no dupes.
Is there a Restangular method that is used to merge as it seems a common use case. (Could be used for loading additional paginated data too.)
Related
I am currently making an application in angular which does this:
(On page load) Make an api call in angular controller (to symfony2 end point) to get: items.
$scope.items = ItemsService.query(function(data){
$scope.loading = false;
}, function(err){
$scope.loading = false;
});
items is an array containing many item objects.
Each item contains parameters e.g. item.param1 item.param2.
I have built it in a similar way to this tutorial:
http://www.sitepoint.com/creating-crud-app-minutes-angulars-resource/
i.e. The angular controller calls a service which calls the (symfony2) backend api endpoint.
The endpoint passes back items which is gets from a database. Items are then put into the view using ng-repeat (item in items).
This all works fine.
Now, I have a button (in the ng-repeat) which effectively causes a PUT request to be made to (another symfony2 endpoint), thus updating item.param1in the database. This also happens in the tutorial I linked to.
The problem is that (in my application and in the tutorial) I have to again make an api call which updates ALL the items, in order to see the change.
I want to just update the data in the view (immediately) for one object without having to fetch them all again.
i.e. something like:
$scope.items[4] = Items.get({id: item.id}, function(){});
Except the application array key isn't known so I cant do that.
(so something like: $scope.items.findTheOriginalItem(item) = Items.get({id: item.id}, function(){});.
Another possible solution (which seems like it may be the best?). I have looked here:
http://teropa.info/blog/2014/01/26/the-three-watch-depths-of-angularjs.html
And tried doing the equality $watch: $scope.$watch(…, …, true);. Thus using watch to see when the item sub-array is updated. This doesn't seem to update the data in the view though (even though it is updating in the database).
Any advice on the best way of doing this (and how to do it) would be great! Thanks!
Essentially the button click should use ng-click to execute a function and pass the item to that function. Example:
...ng-repeat="item in items"...
<button type="button" ng-click="updateItem(item)">Update</button
...
Then in the function you have the exact item that you want to update. If you are using $resources, it would be something like:
$scope.updateItem = function(item) { item.$update(...); };
Unless I didn't understand you
I'm new to AngularJS and need to consume a REST API. I can successfully load the collection of projects from the server using two different ways, but I fail to get a single project from this list (after it's been populated) by its id. I do not want to get the item again from the server.
When I try with angularjs-rails-resource, I can get the list of items using Project.query()and store it in $rootScope.projects. However I now wonder how to get an item out of this list by its id (actually it's not an array but a promise)?
I also tried with restangular using $rootScope.projects = Restangular.all("projects").getList() and project = $rootScope.projects.get(id). But this also fails, because it seems to return a collection and not a single item...?!
For angularjs-rails-resource you should be able to just use get(id). It will always return a promise which is fine if you're using it in your template because templates understand promises.
If you don't want a promise, you can use then
Project.get(1234).then(function (project) {
//project is NOT a promise
$scope.project = project;
});
rather than
//project is a promise, but you're template is cool with that
$scope.project = Project.get(1234);
In order to return single item use:
$scope.project = Project.get(id: some_id);
Here is my problem! I use $resource API to post data from the client side to the server side. After the server side successfully updates the database, I kinda hope my data in view will be updated.
I chose to achieve this with:
$scope.magazines = Magazines.query();
$scope.addMagazine = function() {
var magazine = new Magazines({...payload data});
Magazines.save(magazine, function() {
$scope.magazines = Magazines.query();
});
};
Magazines is a defined ngResrouce factory.
This code works fine. My only problem is, whenever I activate this function (through mouseclick), the view flashes (refreshes) once. It is a really really bad user experience.
I wonder if there is any other way to add the new "magazine" to the scope without refreshing the entire $scope.magazines ?
By the way, the api at the backend will add a few properties (like created time, or id to it). Even if I write code to get the last added item (a different factory method I suppose), I'll still have to add it to the $scope.magazines and I don't know how to do that.
Any thought?
Just push the new Magazine onto the existing $scope.magazines (assuming it's an Array)
var magazine = new Magazines({...payload data});
$scope.magazines.push(magazine);
I have AngularJS application that use $resource service to retrieve data using query() method and create new data using model.$save() method. This works fine exactly as the docs say it should.
My question is how to update my local data fetched using MyService.query() in the first place after I've changed it?
I took the most simple approach for now and I simply call the query() method again. I know this is the worst way efficiency-wise but it's the simplest one.
In my server-side I return the whole state-representation of the new model. How can I add the newly created model to the array of the local data?
UPDATE
I've end up simply pushing the model return from the server but I'll still be happy to know if that's the way to go. From what I can understand from the source code the return array is plan-old-javascript-array that I can manipulate myself.
This is the code I used
$scope.save = function () {
var newComment = new CommentsDataSource();
newComment.Content = $scope.todoText;
newComment.$save({ id: "1" }, function (savedComment) {
$scope.comments.push(savedComment);
});
}
I would simply get the whole list again, to be able to see the modifications brought to the list by other users.
But if the solution you're using suits you, then use it. It's corrrect. Angular uses bare-bones JavaScript objects. Adding a new instance to a list in the scope will refresh the list displayed on the page.
Currently I'm doing a local Backbone app. And I want to know how to save data, specifically, how to construct the url attribute for Collection and Model. I have created a folder called data which is intended to hold the data. But how is the data structured? Is it just a single json file to hold the whole Collection data in it? Or it has many seprate json files to hold each Model's data individually? If it's a single json file, how should I created the url atrributes for both Collection and Model? If they are many separate json files, What should I do?
It is upto you :) . Backbone.Js models, collections work and can be made to work with pretty much any type of data source that expose through HTTP and URL. But it was designed to work against REST based services out of the box. Since you are interested to test the library and learning it i will advice you to stick to static JSON file or even Twitter timeline service.
Since all collections are in single JSOn file you will need just to set the URl for the collection.
View that renders the collection will instantiate the models and render them from the collection
Application
window["Application"] = {};
Application.Model = {};
Application.Collection = {};
Application.Views = {};
Application.Templates = {};
Application.Router = {};
Collection from url
Application.Collection.TimeLine = Backbone.Collection.extend({
url:"data/collection.json"
});
Current Url is http://localhost/timelineapp/index.html
Collection.Fetch will make GET request to http://localhost/timelineapp/data/collection.json
is this not clear enough i will add more detail