Update Angular View after resource post - angularjs

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);

Related

using angularjs to refresh view's data automatically when the data in database is changed

is it possible to use angularJs to refresh view's data automatically when the data in database is changed? Please help me how to do it
I made this script, but as you can see the data only refresh if viewData() is triggered.
$scope.viewData = function(){
$http.get("sample.php").then(function(response){
$scope.mine = response.data;
});
}
I want to create page like timeline in twitter which can load new tweets without refreshing the page. Thank you
You can do longpolling like this from Angular side:
setInterval($scope.vievData, 1000);
since setInterval is not monitored by Angular you will have to add the following line in $scope.viewData
$scope.$$phase || $scope.$digest();
immediately after $scope.mine=...
This will refresh $scope.mine every second regardless of the changes in DB, it is a bit crude. To do this only when the values are changed in the database you will probably have to use WebSockets, but that is a bit more complex, both front and back.

Prevent Firebase $firebaseArray auto update

I am working on a News Feed that is similar to Facebook News Feed. I am implementing it in the following sequence:
When app is started, get everything, but only push two item to show.
The user can scroll down to see more and I will add more to the list.
If there are any new items, the user needs to pull to refresh to add the new ones.
The only problem I have right now is that each time an item is added, $firebaseArray automatically adds the new item to my array that I do not want snyc changes (I want to query once, get a set list). I was wondering if anyone would know how to prevent the auto update?
Look into .once this will allow you to get the data just once: https://firebase.google.com/docs/reference/js/firebase.database.Query#once
Instead of binding directly your $firebaseArray to the view, clone it to a scope (or controller) property that will be bound to the view. Factorize this process in a function you can call when the user pull-reloads so the the $firebaseArray is re-created.
A more appropriate approach would be to use Firebase's http api, with the angular $http service.
Edit: to clone the array to a scope var, try the following:
var allEvents = $firebaseArray(queryOfeverything);
allEvents.$loaded()
.then(function(events){
$scope.allEvents = angular.map(events, function(event) {
return event; // you may want to replace this line - I am not very familiar with firebase.
})
});

How to disable firebase 3-way data binding

I am using angularJS 1.3 with angularfire and firebase.
I did create some factories that encapsulate the firebase object, and it works very well. The 3 way data binding is really cool.
I am planning to build a large application using firebase for data persistance, but I am facing a massive issue :
In my business model, I want some models/collections to support 3-way data binding, but I want other collections not to be updated live.
Some clients visiting the resulting website might be scared when they see the website's content being updated live - and I don't want that.
Imagine you are reading an article , somehow long and complexe, and you put your attention into a paragraph which you have issues understanding, and suddenly, the paragraph disappears and is replaced by a new one. Now imagine that you have no idea about web development. You might start to think to consult some professionnal about your mental health, or think your computer is hacked. Who knows !
So I would like to disable the 3 way data binding for this article, and avoid this border-line client phone calls. The only solution I found would be not to use fireangular, and use the beyond angularfire documentation section instead, and remove the following lines :
ref.on("value", function(snapshot) {
$timeout(function() {
$scope.data = snapshot.val();
});
});
This would fix the issue, but then in my admin interface, I would have to implement a second Factory so admin users can access the 3 way data binding for articles - Which is not very DRY.
In my artitcle controller, I would have to write something like this :
$scope.loadArticle = function(){
if(UserService.type === 'admin'){
AdminArticleFactory.get(id);
}
else{
ArticleFactory.get(id);
}
}
Is there any other way of setting up firebase to disable the pull updates?
Yeah, that is what I also ran into. Sometimes you will repeat yourself with Firebase. Also when storing data. I would recommend just making a function to save the data that you don't want to be updated instantly.
<button ng-click="saveChanges">save</button>
In controller
$scope.saveChanges = function () {
var obj = $firebaseObject(ref);
obj.foo = "bar";
obj.$save().then(function(ref) {
ref.key() === obj.$id; // true
}, function(error) {
console.log("Error:", error);
});
}
edit
To desync a firebase object/array you can follow this answer: How to disassociate angularFire bound object?

Backbone try to update model in server after save

I use Rails 4 + backbone in my application.
Everything is good. New model is created in backbone and saved by calling:
newItem.save(null, {success: this.sendSuccess, error: this.sendError});
However, implementing a new feature I need to change one of the model attributes. What I see that a PUT action is fired just before sendSuccess is called, which I want to avoid.
Moreover, the url is very strange. Save action calls this url:
Remote Address:127.0.0.1:3000
Request URL:http://www.lvh.me:3000/api/user/1/tickets
Request Method:POST
and then, after server return the json with the modified attribute, backbone calls this url:
Remote Address:127.0.0.1:3000
Request URL:http://www.lvh.me:3000/api/user/1/tickets
Request Method:PUT
without the ticket id!
Is there any way to prevent backbone fire an update when server return the model with different attributes?
The problem was that I had a listener in my model exactly on the column that server changed:
initialize: function() {
this.on("change:status", this.statusChanged, this);
},
Now I had to figure out why the update url does not contain the model id.
I figured out that when I first created the model, from some reasons I couldn't assign it to the collection, so in order to save it I assign the url manually:
var newTicket = new MyApp.Ticket( ticketData );
newTicket.url = this.collection.url();
Now, the bug is that url is a function, and I simply overrided it!
I changed the code to:
newTicket.urlRoot = this.collection.url();
and now it works.
Backbone will always perform PUT if your model has an id attribute setted. Which makes sense when using RESTfull.
Be sure that you're really SAVING(new model withoud an ID) a data to server instead of UPDATING(model with an ID) to server.

How to refresh local data fetched using $resource service in AngularJS

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.

Resources