I'm working on chatting application in firebase and angular. When I send message using $scope.send(message) function it's directly upend to $scope.messages array because of three-way binding of angularfire. It's initially stored in locally and sync with server in background. I want to keep track message's status if it's sync with server or not. AngularFire's $push method has callback when it's sync with server. But I'm getting no clue of how to keep track of data is "In flight" ( Not synched with server but added in angular scope variable.)
var Ref = new Firebase('FIREBASE_APP_URL');
var ref = Ref.child('messages');
$scope.messages= $firebaseArray(ref).orderByChild('createdAt').limitToLast(10));
$scope.send = function(message) {
$scope.messages.$add(message).then(function(ref) {
var id = ref.key();
console.log("added record with id " + id);
console.log($scope.messages.$indexFor(id)); // returns location in the array
});
}
The $firebaseArray object is not involved in any three-way data binding. That is limited to $firebaseObjects .bindTo() method.
What happens when you call $add() is that a local child_added event is immediately raised and the $firebaseArray updates its internal data based on that. This is how all Firebase clients work, not just AngularFire, and it is part of why Firebase appears to work instantaneous.
If you want to know when the item was added on the server, you can use the promise that $add() returns. When that promise resolves, the data has been committed on the server.
From the AngularFire documentation for $add():
This method returns a promise which is resolved after data has been saved to the server.
var list = $firebaseArray(ref);
list.$add({ foo: "bar" }).then(function(ref) {
var id = ref.key();
console.log("added record with id " + id);
list.$indexFor(id); // returns location in the array
});
Related
I got the following AngularJS sample code from the document regarding how to add a new record to Firebase. It works fine and the new record can be created successfully.
While I also noticed that from the callback we can get all the siblings with the list variable, which is interesting.
My question is that would there be any performance latency when the list is large, say 100,000 records. Can anyone shed light on this?
var list = $firebaseArray(ref);
list.$add({ foo: "bar" }).then(function(ref) {
var id = ref.key();
console.log("added record with id " + id);
list.$indexFor(id); // returns location in the array
});
$firebaseArray synchronizes a collection from the Firebase Database to your client, for easy display in your Angular views. You should never synchronize more data than the user needs to see, and 100,000 records seems very much beyond what a user should ever see.
If you just want to add a new item, you're better off using the Firebase JavaScript SDK directly:
ref.push({ foo: "bar" }).then(function(ref) {
var id = ref.key();
console.log("added record with id " + id);
});
Since AngularFire is built on top of the Firebase JavaScript SDK, it will pick up this change automatically.
So i am currently running into this problem
I have select options which value are retrieved from DB. I use ui-router, and in the controller i always set if(vm.action == 'blabla') then it will call a function then retrieve the data from the webservice.
The problem is, when I am calling more than 2 data(example products and tax select choices). How can i run a function after particular select options has been successfully retrieved from DB?
Take an example, i am doing quotation to invoice module. There are tax and products. These 2 retrieved from DB. in the ajax call after I retrieved the products succesfully, I directly run another function that will calculate all the prices and tax. But somehow, the tax has not been successfully loaded into vm.options.tax after all the products have been loaded successfully
I have tried using $scope.watch('vm.options.tax',function()) but it just gives me undefined in the first place and didn't update me once the vm.options.tax has been loaded with data from DB.
how can i 'wait' for the vm.options.tax has been loaded and then run the function?
Thank you
When you're using scope.watch, it will triggered once the dom first fully loaded and when the model value changed. When the dom is load, the process of retrieving data from db isn't finish, that's why you get undefined value. You can use angular promise. The semantics of Angular dictate that you use promises as a sort of 'callback handle' - do something asynchronous in a service, return a promise, and when the asynchronous work is done, the promise's then function is triggered.
var populateTax = function() {
return $http.get('/api/get_all_tax')
.then(
function (response) {
// Calculate pricing here
var pricing = response.data * tax;
},
function (httpError) {
// translate the error
throw httpError.status + " : " +
httpError.data;
});
};
I want to retrieve data from firbase with a condition like this
ref.orderByChild('users').equalTo(userid).on('value', function(snapshot) {
// Need to return data as firebaseArray here
});
$firebaseArray is very useful when we want to show data on view. But I don't know how to return the snapshot there.
Please help me ! (bow)
A $firebaseArray can take in a ref or a query.
var query = ref.orderByChild('users').equalTo(userid);
var syncArray = $firebaseArray(query);
The array function handles all the child events and keeps the array in sync with the remote server changes.
I am implementing a notification system using angularjs and meteor.
In my publication code,
I have something like this:
var retVal = Notifications.find({recipient: userId});
var handle = retVal.observeChanges({
//when a new notification is added
added: function (doc, idx) {
count++;
if (!initializing){
console.log("A record was added");
self.changed("counts", userId, {count: count});
}
},
removed: function (doc, idx) {
count--;
self.changed("counts", userId, {count: count});
}
});
and in the end I return retVal.
In my controller, I subscribe to that publication.
The code seems fine and the server triggers the added function whenever a new document is added. But how do I notify the client (something like trigger a function in my controller) when a new document is added? The added function only triggers in the server.
I can't see your publication header, do you expect parameters there?
For binding a collection all you need to do is use the $meteorCollection service like that:
$scope.notifications = $meteorCollection(Notifications);
We just updated our API (version 0.6.0-alpha) and it does observeChanges internally to look for any change in the collection.
But don't forget to subscribe to that collection - you can do that in 2 ways:
$meteorSubscribe.subscribe("publicationName", parameters) - which returns a promise.
$scope.notifications = $meteorCollection(Notification).subscribe("publicationName", parameters); - which is shorter but doesn't return a promise.
If one of the parameters changes the publication, you should surround it with autorun like that:
$meteorUtils.autorun($scope, function(){
$meteorSubscribe.subscribe("publicationName", {
limit: parseInt($scope.getReactively('perPage')),
skip: (parseInt($scope.getReactively('page')) - 1) * parseInt($scope.getReactively('perPage')),
sort: $scope.getReactively('sort')
}));
});
$scope.getReactively is a new method we added that makes a regular $scope variable to a reactive one. this means that when it changes, that autorun will re-run.
Hope it helps, let me know how can I improve the answer and the documentation.
I think that you should replicate your observeChanges() on the client.
So, it will be able to observe the client side collection that is created and synchronized by the subscribe() function.
So basically, I created a Backfire app. As soon as the page is loaded, I am iterating over my Backbone.Firebase.Collection instance.
And then rendering the results onto the page... the problem is that obviously the collection instance does not contain all the data that is on firebase.
So, I put a set-timeout of 1000ms to make it so that the collection has time get its data from Firebase. This way of doing it is terrible... sometimes the data is synced up other times it is not.
How can I have an event be triggered as soon as the "BackFire Collection Model" has its data from firebase?
$(document).ready(function() {
var myCatalogApp = new CatalogApp()
var catalog = new Catalog()
setTimeout(function(){myCatalogApp.displayCollection(catalog)},1000);
//To give catalog time to asynchronously retrieve database entries
myCatalogApp.initialize()
})
var Catalog = Backbone.Firebase.Collection.extend({
model: Item,
firebase: "https://mycatalogmaker.firebaseIO.com/items"
});
All of my problems would be solved if Backfire would let me do a fetch method... but they have it disabled for Backfire objects
Try this :
$(document).ready(function() {
var myCatalogApp = new CatalogApp()
var catalog = new Catalog();
catalog.bind('sync', function(){myCatalogApp.displayCollection(catalog);});
myCatalogApp.initialize();
})