I am creating arrays using Angularfire but I am unable to set the key name. Firebase is automatically giving me a cryptic key (eg Jm9vLy8Lye-KS35KsmL) but I would like to set it myself to something more meaningful. It is unclear how I do this in Angularfire. I am using the $add method on $firebaseArray:
var firebaseRef = new Firebase("https://firebase_location");
$scope.messages = $firebaseArray(firebaseRef);
$scope.messages.$add(
{
FirstName: patient.FirstName,
LastName: patient.LastName
}
).then(function(firebaseRef) {
var id = firebaseRef.key();
});
The data is stored fine and I can see it on my dashboard. However, id is always a cryptic firebase value. I would love to be able to set it myself to something meaningful. In my case the individual patient's ID would be meaningful...
Any thoughts?
Thank you!
Thanks for the response.
I found that the child function will do what I need. I first specify the child and then set it.
var patient_child = firebaseScreenRef.child(patient.PatientId);
patient_child.set(
{
FirstName: patient.FirstName,
LastName: patient.LastName,
});
Adding an item to a firebase array make firebase define a unique id for you. If this is not what you want, I think you can try getting the "messages" object with $firebaseObject, instead of getting just the list with $firebaseArray. Then you will be able to edit your object in js, in order to add your items to the messages collection. In this way you can use the id that best suits your needs. Finally, you have to $save() your entire object. Look here: https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebaseobject
Hope this helps.
For your question, I found an explanation. You don't need to use firebaseObject, you should use ref directly:
var ref = new Firebase(FURL);
createProfile: function(id ,user) {
var profile = {`enter code here`
name: user.name,
email: user.email,
gravatar: get_gravatar(user.email, 40)
};
var profileRef = $firebaseArray(ref.child('profile').child(id));
return ref.child('profile').child(id).set(profile);
},
In the code, I use ref to reference my URL. With profileRef, I created a child profile and I added id for the profile. Afterwards, I use ref directly to set the value profile for the id that I want. You see, it is very easy.
Related
Programmatically
So I am facing an issue with the select in Angular JS. This is a follow-up question to my previous question
Now I am able to load my values in the second select but I am unable to write the same value to it when the query from DB comes back. So If I select Ford in one select and Figo in another. and press save. The values go into DB correctly but when I come again to that view. Shouldn't that value persist right? I mean I should be able to see figo in the second select. But I am unable to. I tried setting to the ng-model but that method doesn't work. I have also attached a fiddle with the proper comments as to what is not working.
The code uses one of the marked answers from the question.
HTML
<select ng-model="carBrand" name="carBrand" required ng-options=" brand for brand in brands" ng-change="selectedCar(carBrand)"></select>
<select ng-model="carModel" name="carModel" required ng-options="model.name for model in cars[carIndex]"></select>
JS
$scope.brands = ['Ford', 'Honda', 'Hyundai', 'Mahindra',
'Maruti Suzuki', 'Nissan', 'Renault', 'Skoda', 'Tata', 'Toyota', 'Volksvagen'
];
$scope.cars[0] = $scope.cars[0] = [{
name: "Figo",
capacity: 45
}, {
name: "Ecosport",
capacity: 52
}, {
name: "Fiesta",
capacity: 45
}, {
name: "Endeavour",
capacity: 71
}];
$scope.carBrand = $scope.brands[0];
$scope.cars = [];
$scope.selectedCar = function(brand) {
$scope.carIndex = $scope.brands.indexOf(brand);
};
$scope.carModel = "Anything";
EDIT
I think there is an issue in the understanding of the question. All I want is programmatically(by code) set the value of the second select. That's it.
I have forked your fiddle. Have a look: https://jsfiddle.net/4ynkrj0o/2/
var MockSaveMyData = function(itemsToSave){
// I JUST SAVED ALL MY DATE !! :D
var savedItems = itemsToSave;
savedItems.CreatedAt = new Date();
savedItems.CreatedBy = 'YOU !!';
return {
then: function(callback){
callback(savedItems);
}
};
};
You will have to save and retrieve the values on every page refresh.
Like you said, you have cookies where you save your Car object. In that case, you will have to assign the object on the top firth thing inside the controller.
You will also have to update the cookies after you have run the save function. I will suggest doing all this in the success call back which http calls provide. You can update the cookie and then refresh the page. Or you can just assign the updated values and give a message to the user stating that the save call has been successful.
Again, in my opinion, you should avoid reloading the page. It almost defies the essence of Angular. Where you can do almost everything asynchronously.
Is there any way to on Firebae to filter data in an array?
I have this model on my Firebase:
-KABIGeWnBMUKjLTcvp8
deviceToken:"7DE60240CB4B712F05A009F32358610C1327917E7E68409..."
favorites
0:"Masha"
1:"moksha"
name:"juan"
And the problem is that I can't find any method to get all "users" that contain a certain value on the "favorites" array field.
Nope, that's not an option See firebase equivalent to sql where in ().
Instead: invert your data structure to make this query possible:
items_by_favorites
"Masha"
"-KABIGeWnBMUKjLTcvp8"
"moksha"
"-KABIGeWnBMUKjLTcvp8"
Now you can look up the item keys for Masha with a simple read: ref.child('items_by_favorites/Masha') and then load each item:
ref.child('items_by_favorites/Masha').on('value', function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key();
ref.child('items').child(key).once('value', function(itemSnapshot) {
console.log(itemSnapshot.val());
});
});
})
First of all your question is answered deep in the guide for retrieving data, which is where I got this answer. It's under complex queries, then range queries, should you want more info.
var ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
ref.orderByChild("height").equalTo(25).on("child_added", function(snapshot) {
console.log(snapshot.key());
});
The basic idea is that you need to first order the reference by a common child value, and then call .equalTo() to end up with a query that yields what you want.
Also you can call order by child like
ref.orderByChild("height/sublevel")
To drill deeper in the tree.
FirebaseFirestore.instance.collection('your collection name').where('favorite', arrayContains: 'Masha').snapshot();
Say I'd like to fetch only items that contains keys: "-Ju2-oZ8sJIES8_shkTv", "-Ju2-zGVMuX9tMGfySko", and "-Ju202XUwybotkDPloeo".
var items = new Firebase("https://hello-cambodia.firebaseio.com/items");
items.orderByKey().equalTo("-Ju2-gVQbXNgxMlojo-T").once('value', function(snap1){
items.orderByKey().equalTo("-Ju2-zGVMuX9tMGfySko").once('value', function(snap2){
items.orderByKey().equalTo("-Ju202XUwybotkDPloeo").once('value', function(snap3){
console.log(snap1.val());
console.log(snap2.val());
console.log(snap3.val());
})
})
});
I don't feel that this is the right way to fetch the items, especially, when I have 1000 keys over to fetch from.
If possible, I really hope for something where I can give a set of array
like
var itemKeys = ["-Ju2-gVQbXNgxMlojo-T","-Ju2-zGVMuX9tMGfySko", "-Ju202XUwybotkDPloeo"];
var items = new Firebase("https://hello-cambodia.firebaseio.com/items");
items.orderByKey().equalTo(itemKeys).once('value', function(snap){
console.log(snap.val());
});
Any suggestions would be appreciated.
Thanks
Doing this:
items.orderByKey().equalTo("-Ju2-gVQbXNgxMlojo-T")
Gives exactly the same result as:
items.child("-Ju2-gVQbXNgxMlojo-T")
But the latter is not only more readable, it will also prevent the need for scanning indexes.
But what you have to answer is why want to select these three items? Is it because they all have the same status? Because they fell into a specific date range? Because the user selected them in a list? As soon as you can identify the reason for selecting these three items, you can look to convert the selection into a query. E.g.
var recentItems = ref.orderByChild("createdTimestamp")
.startAt(Date.now() - 24*60*60*1000)
.endAt(Date.now());
recentItems.on('child_added'...
This query would give you the items of the past day, if you had a field with the timestamp.
You can use Firebase child. For example,
var currFirebaseRoom = new Firebase(yourFirebaseURL)
var userRef = currFirebaseRoom.child('users');
Now you can access this child with
userRef.on('value', function(userSnapshot) {
//your code
}
You generally should not be access things using the Firebase keys. Create a child called data and put all your values there and then you can access them through that child reference.
I have a question about adding arrays to Firebase using AngularFire. Let's start with a quick example. What I tend to do when my users on the front end create a list is something like this:
angular.module("app", ["firebase"])
.controller("createListCtrl", function($scope, $firebaseArray) {
console.log("controller loaded");
$scope.newList = [];
$scope.addItemToList = function(itemlist) {
console.log(itemlist);
$scope.newList.push({
"item": itemlist,
"done": false
});
}
$scope.sendToDb = function() {
var ref = new Firebase("https://xxxxxx.firebaseio.com");
var list = $firebaseArray(ref);
list.$add({
"list": $scope.newList
}).then(function(ref) {
var id = ref.key();
console.log("added record with id " + id);
console.log(list.$indexFor(id)); // returns location in the array
})
}
Ok all nice and dandy and it all works great but I then I read this article:
https://www.firebase.com/blog/2014-04-28-best-practices-arrays-in-firebase.html
And I heard more people say to avoid arrays and I see the problem with array in Firebase, but what is the alternative, the article says this structure:
{foo: {counter: 1}, bar: {counter: 1}, baz: {counter: 1}};
Is that really a better structure? I think it gets messy and I don't even know how I would achieve this structure starting with something like this:$scope.newList = {};. Is it really a problem doing it with an array. Are arrays really evil in Firebase? Thanks in advance for an explanation or a better alternative.
edit
This is how the list is stored in Firebase, which does not seem very good:
---uniqueID
---list
---0
---done:false
---item:"item1"
---1
---done:false
---item:"item2"
---2
---done:false
---item:"item3"
The $firebaseArray class, which you're already using, provides a mapping between Firebase's ordered collections (which use push ids for their keys) and AngularJS's array (which use regular arrays).
So in your controller's constructor instead of creating a local array for itemList, create a two-way synchronized $firebaseArray:
$scope.newList = $firebaseArray(new Firebase("https://xxxxxx.firebaseio.com"));
The blog post you're referring to served as the basis for quite a few changes to AngularFire since then. I highly recommend that you work through the AngularFire development guide. It will take at most a few hours and will answer many more questions than just this one (which is covered in the section on synchronized arrays).
Update
Thanks for the update. I now get what you're trying to do. So you initially want to keep the list of items client-side only, and then all at once save it to Firebase.
In that case, I'd write sendToDb like this:
$scope.sendToDb = function () {
var ref = new Firebase("https://xxxxxx.firebaseio.com");
var listRef = ref.push();
$scope.newList.forEach(function(item) {
var itemRef = listRef.push({ item: item.item, done: item.done });
console.log('Added item with key: '+itemRef.key());
});
}
This uses the regular Firebase JavaScript SDK. But since AngularFire is built on top of that, they will co-exist without problems.
So instead of pushing the array in one go, I simply loop over the items in it and push each of them.
Working fiddle here: https://jsfiddle.net/frankvanpuffelen/vnh5dbwq/11/
I have a button with a handler. In this handler I call for this function:
onAddClick = function() {
gridStore = Ext.getStore('gridEdit');
var rec = new gridStore({
stopCode: '',
stopOrder: '',
stopId: ''
}), edit = this.editing;
edit.cancelEdit();
this.store.insert(0, rec);
edit.startEditByPosition({
row: 0,
column: 1
});
};
When I click on the button it will give the error message: "gridStore is not a constructor". Why is this?
You have a lot of errors in the code, first of all, once you use Ext.getStore, it returns an store with that id (the store is already created). So the gridStore (global variable, since you haven't use var) will point to that store.. So no need for new.
If you want to add custom config, just use Ext.create().
The var 'rec' .. should that supposed to be a record from the store?
I don't know what you are trying to do exactly but:
-gridStore is the actual store;
-a record can be created by modelManager or by Ext.create and the model class.