How to retrieve child value from child in firebase with javascript? - javascript

var ref = firebase.database().ref("games/" + gameId + "/patterns");
ref.on("child_changed", function(snapshot){
var pattern = snapshot.key;
console.log(pattern);
});
This is giving only the key.
What if I want to extract the player name whose status = 0
I know the snapshot contains every child data I need to extract because when i use
var ref = firebase.database().ref("games/" + gameId + "/patterns");
ref.on("child_changed", function(snapshot){
var value = snapshot.val();
console.log(value);
});
I am getting the data like this..
I am not able to get the child's data as needed.

The value you extract is a regular JavaScript/JSON object, so you can access its members as you would do with any other JavaScript object. Your 1, 2, 3 level keys will be converted to an array by Firebase, which means it adds a null item at the start of that array. For more about that, see: Firebase database returns null at beginning of each new node
To loop over all child nodes under the child of patterns that was changed and get the players whose status is 0 you'd do something like:
var ref = firebase.database().ref("games/" + gameId + "/patterns");
ref.on("child_changed", function(snapshot){
snapshot.forEach(function(child) {
if (child.val() && child.val().status == "0") {
console.log(child.val().player);
});
});
});

Related

How to remove only one specific data which appears multiple time in localStorage

I have items that I add to the cart by storing them in a localStorage with their ID.
$(document).on('click', '.set-cart-info', function () {
// We retrieve the product id which is stored in the url
var url_id = window.location.search;
var id = url_id.split('?id=').pop();
// We retrieve the data from the localStorage
var cartItems = localStorage.getItem('teddy_id');
// If there is no data, we create an array
cartItems = cartItems ? cartItems.split(',') : [];
// Add the new data to the array
cartItems.push(id);
// We save the data in the localStorage
localStorage.setItem('teddy_id', cartItems.toString());
});
In the console.log I get this :
localStorage.getItem('teddy_id')
"5beaacd41c9d440000a57d97,5beaabe91c9d440000a57d96,5beaabe91c9d440000a57d96,5beaaa8f1c9d440000a57d95,5beaabe91c9d440000a57d96,5beaaa8f1c9d440000a57d95,5beaabe91c9d440000a57d96,5beaacd41c9d440000a57d97,5beaaa8f1c9d440000a57d95,5beaaa8f1c9d440000a57d95,5beaaa8f1c9d440000a57d95,5beaabe91c9d440000a57d96,5beaacd41c9d440000a57d97,5beaacd41c9d440000a57d97,5beaacd41c9d440000a57d97,5beaacd41c9d440000a57d97,5beaacd41c9d440000a57d97,5beaaa8f1c9d440000a57d95"
Then, I added the possibility of adding or removing a quantity of a product by retrieving the product ID and adding it to the localStorage, my problem is as follows: when I retrieve the ID to fetch it in the localStorage, it deletes all items with this ID, I would like it to remove only one.
Here is the code that allows to add a quantity, and the one that should be modified so that it also removes only one :
$(document).on('click', '.add_qty', function () {
// We retrieve the product id which is stored in the class
var split_class = this.className.split(' ');
var this_id = split_class[1];
var cartItems = localStorage.getItem('teddy_id');
cartItems = cartItems ? cartItems.split(',') : [];
cartItems.push(this_id);
localStorage.setItem('teddy_id', cartItems.toString());
});
$(document).on('click', '.remove_qty', function () {
// We retrieve the product id which is stored in the class
var split_class = this.className.split(' ');
var this_id = split_class[1];
var cartItems = localStorage.getItem('teddy_id');
cartItems = cartItems ? cartItems.split(',') : [];
// This is the part that retrieve the product by his ID and delete all product with this specific ID
var newStorage = cartItems.filter(function(r) { return r !== this_id});
localStorage.setItem('teddy_id', newStorage.toString());
});
$('.product_in_cart' + '.' + ID._id).append('
<td class="product_in_cart_changeqty">
<button onClick="window.location.reload()" class="add_qty ' + ID._id + '">+</button>
<button onClick="window.location.reload()" class="remove_qty ' + ID._id + '">-</button>
</td>');
Thanks in advance for your time and help :)
Always remember that array methods are your friend. One way you could do this is combine the use of array.prototype.find() with array.prototype.splice() as follows:
cartItems.find( ( item, i ) => {
if ( item == this_id ) {
cartItems.splice( i, 1 );
return true;
}
return false;
} );
This way, it’s only removing the first matching item that it comes upon.
your problem is with the use of local storage once you store ID array its gets stored in the form of an array while retrieving the data you need to fetch the string json parse it and then run the required operation. Check this eg.

How can I get the name of a property from inside an object to create a new property name?

I know there are a few other posts on this topic, but they don't seem to address my issue: link.
I want to be able to dynamically get the name of a specific property in an object so that I can use it to create a new property name inside another object. For example, I would get the property name startMin from foo (as in my code below) and then add text to the end of it (like startMin + Suffix) to create a new property name. How can I do this?
A related note: I've already figured out how to get the property value with foo[Object.keys(foo)[0]]. Though this works, I'm not sure why Object.keys gets the property value in this case since the examples I've found suggest Object.keys is supposed to get the property name not the property value. I'd love to know why?
I have included the pusdo code foo[Object.returnObjectName(foo)[0]] + 'Cal' where I want the name to be dynamically created. It doesn't work, of course.
var foo = {
startMin: 1000
};
var fooResults = {
// the property name here is psudo code
foo[Object.returnObjectName(foo)[0]] + 'Cal': foo[Object.keys(foo)[0]]
}
console.log('startMinCal: ' + fooResults.startMinCal) // This should log "1000" but won't until the object name inside `fooResults` is created correctly.
//
console.log(Object.keys(foo)); // I believe this gests the property name, but it exists inside an array, so won't work as a new property name
console.log(foo[Object.keys(foo)[0]]); // this gets the property value as expected.
UPDATED WORKING CODE:
var foo = {
startMin: 1000,
startMax: 3000
};
var fooResults = {
[Object.keys(foo)[0] + 'Cal']: foo[Object.keys(foo)[0]],
[Object.keys(foo)[1] + 'Cal']: foo[Object.keys(foo)[1]]
}
console.log('startMinCal: ' + fooResults.startMinCal)
console.log('startMaxCal: ' + fooResults.startMaxCal)
var foo = {
startMin: 1000
};
//Object.keys return all the keys in an object passed as parameter
//here your wanted key is at first position
var key = Object.keys(foo)[0];
//get the value
var value = foo[key]
//append whatever suffix you want
key += 'Cal';
var fooResults = {
//to use content of variable as key of object put variable in []
[key]: value
}
//another solution
//create emtyy object
var fooResults2 = {}
//use use variable name as index
fooResults2[key] = value
console.log('startMinCal: ' + fooResults.startMinCal) // This should log "1000" but won't until the object name inside `fooResults` is created correctly.
console.log('startMinCal: ' + fooResults2.startMinCal)

Order data in Firebase

I'm new to Firebase, and I'm going to build a list of item collected from server with following criterias:
max 10 items
order by item value (eg. 'count')
this is my code
FBRef.orderByChild("count").limitToLast(10).on("child_added", function(snapshot){}
and it worked fine, but when a new record inserted, is there a Firebase method that can check and auto update the list if the new item is in top 10 ? Or I need to to it myself ?
var FBRef = new Firebase('yours.firebaseio.com');
FBRef.orderByChild("count").limitToLast(5).on("child_added", function(snapshot){
var data = snapshot.val();
var html = "<li>value: " + data.value + " - count: " + data.count + "</li>";
$("#result").prepend(html);
});
$(document).ready(function () {
$("#inputaddbtn").click(add);
});
function add(){
var value = $("#inputvalue").val();
var count = $("#inputcount").val();
$("#inputcount").val("");
$("#inputvalue").val("");
FBRef.push({
value : value,
count : count
})
}
You'll need to monitor more events and handle more arguments to keep the list limited.
As a first step: Firebase will fire a child_removed event when an element has been removed from the location or (in your case) falls outside of the query.
You can handle that event to remove the child from the list:
var FBRef = new Firebase('yours.firebaseio.com');
var query = FBRef.orderByChild("count").limitToLast(5);
query.on("child_added", function(snapshot){
var data = snapshot.val();
var html = "<li id='key_"+snapshot.key()+"'>value: " + data.value + " - count: " + data.count + "</li>";
$("#result").prepend(html);
});
query.on("child_removed", function(snapshot){
$('#key_'+snapshot.key()).remove();
});
You'll note that I give the li an id when the child is added and then remove the li based on that id when Firebase tells me to.
This covers simple adding/removing items. For a complete app that handles all cases, you should also handle child_changed and child_moved. And you'll probably also want to handle the second argument to the callbacks, which indicates the key of the item that the child needs to go after. But maybe your use-case doesn't require handling these cases, in which case the above is enough.

How to pass a formatted query to findOne() in mongo using node.js

I've one Restful service developed using node.js which takes some values from a user. According to the values given it reformats a query string. But, Whenever I want to pass this query to findone() of mongoDB and calls that service it showing "query selector must be an object" message on browser.
var query = "{" ;
if( orderNo == " "){
// Don't append anything
}else{
query = query + "'orderNo' : " + orderNo ;
}
.
.
.
query = query + "}";
And, I also tried like below :
var query = {};
query[orderNo] = orderNo;
db.collection('*****').findOne(query, function(err, item) {
console.log(item);
res.jsonp(item);
});
In both cases I'm getting the same result in browser.
Anyone guide me how I can query these kind of queries in MongoDB.
You were almost there on your second attempt. When you do this
var query = {};
query[orderNo] = orderNo;
you create an object with key name the same as the value! For example, if the value of orderNo is 12345, then the above statement will produce the object
query = {
"12345": 12345
}
You could use the same bracket notation to create a proper query object property
query = {
"orderNo": 12345
}
as follows:
var query = {};
if(orderNo != " ") query["orderNo"] = orderNo;
db.collection('*****').findOne(query, function(err, item) {
console.log(item);
res.jsonp(item);
});

Numerically ordered ID's of data objects in Firebase

I am pretty new to the 'game' and was wondering if it's possible to order newly added data (through a form and inputs) to the Firebase numerically so each new data entry gets the ID (number of the last added data +1).
To make it more clear, underneath you can find a screenshot of how data is currently being added right now. The datapoint 0-7 are existing (JSON imported data) and the ones with the randomly created ID belong to new entries. I would like to have the entries to comply to the numbering inside of my Firebase, because otherwise my D3 bar chart won't be visualised.
var firebaseData = new Firebase("https://assignment5.firebaseio.com");
function funct1(evt)
{
var gameName = $('#nameInput').val();
var medalCount = $('#medalsInput').val();
var bool = $('#boolInput').is(':checked');
firebaseData.push().set({games: gameName, medals: medalCount, summergames: bool});
evt.preventDefault();
}
var submit = document.getElementsByTagName('button')[0];
submit.onclick = funct1;
UPDATE:
function funct1(evt)
{
var gameName = $('#nameInput').val();
var medalCount = $('#medalsInput').val();
var bool = $('#boolInput').is(':checked');
for (var i = 0; i < 10; i++)
{
firebaseData.child('7' + i).set({games: gameName, medals: medalCount, summergames: bool}(i)); };
Problem:
There are two ways to generate ids for your document nodes.
Calling .push() on your reference will generate that unique id.
Calling .set() on your reference will allow you to use your own
id.
Right now you're using .push().set({}), so push will generate an new id and the set will simply set the data.
// These two methods are equivalent
listRef.push().set({user_id: 'wilma', text: 'Hello'});
listRef.push({user_id: 'wilma', text: 'Hello'});
Using .set() without .push() will allow you to control your own id.
Using .push():
When managing lists of data in Firebase, it's important to use unique generated IDs since the data is updating in real time. If integer ids are being used data can be easily overwritten.
Just because you have an unique id, doesn't mean you can't query through your data by your ids. You can loop through a parent reference and get all of the child references as well.
var listRef = new Firebase('https://YOUR-FIREBASE.firebaseio.com/items');
// constructor for item
function Item(id) {
this.id = id;
};
// add the items to firebase
for (var i = 0; i < 10; i++) {
listRef.push(new Item(i));
};
// This will generate the following structure
// - items
// - LGAJlkejagae
// - id: 0
// now we can loop through all of the items
listRef.once('value', function (snapshot) {
snapshot.forEach(function (childSnapshot) {
var name = childSnapshot.name();
var childData = childSnapshot.val();
console.log(name); // unique id
console.log(childData); // actual data
console.log(childData.id); // this is the id you're looking for
});
});
Within the childData variable you can access your data such as the id you want.
Using .set()
If you want to manage your own ids you can use set, but you need to change the child reference as you add items.
for (var i = 0; i < 10; i++) {
// Now this will create an item with the id number
// ex: https://YOUR-FIREBASE.firebaseio.com/items/1
listRef.child('/' + i).set(new Item(i));
};
// The above loop with create the following structure.
// - items
// - 0
// - id: 0
To get the data you can use the same method above to loop through all of the child items in the node.
So which one to use?
Use .push() when you don't want your data to be easily overwritten.
Use .set() when your id is really, really important to you and you don't care about your data being easily overwritten.
EDIT
The problem you're having is that you need to know the total amount of items in the list. This feature is not implemented in Firebase so you'll need to load the data and grab the number of items. I'd recommend doing this when the page loads and caching that count if you really desire to maintain that id structure. This will cause performance issues.
However, if you know what you need to index off of, or don't care to overwrite your index I wouldn't load the data from firebase.
In your case your code would look something like this:
// this variable will store all your data, try to not put it in global scope
var firebaseData = new Firebase('your-firebase-url/data');
var allData = null;
// if you don't need to load the data then just use this variable to increment
var allDataCount = 0;
// be wary since this is an async call, it may not be available for your
// function below. Look into using a deferred instead.
firebaseData.once('value', function(snapshot) {
allData = snapshot.val();
allDataCount = snapshot.numChildren(); // this is the index to increment off of
});
// assuming this is some click event that adds the data it should
function funct1(evt) {
var gameName = $('#nameInput').val();
var medalCount = $('#medalsInput').val();
var bool = $('#boolInput').is(':checked');
firebaseData.child('/' + allDataCount).set({
games: gameName,
medals: medalCount,
summergames: bool
});
allDataCount += 1; // increment since we still don't have the reference
};
For more information about managing lists in Firebase, there's a good article in the Firebase API Docs. https://www.firebase.com/docs/managing-lists.html

Categories

Resources