I am trying to retrieve data from two tables in a database. But with child it is not working
I have this:
offers{
"id" : {
"quantity": "50%"
"store" : {
"id" : true
}
}
"store":{
"id":{
address:"location"
"users":{
"id": true
}
}
}
"users" : {
"name": "tom",
"lastname": "levine"
}
this is my structured data I want to get all child data from my table something like this:
{
"quantity":"50%",
"store":{
address:"location",
"users":{
"name": "tom",
"lastname": "levine"
}
}
}
}
I have this
const db = firebase.database();
db.ref('offers').child(id).once('value', (data) =>{
console.log(data.val())
}
but if I add another .child(store) then just return the stores id of that offer
I have the offer id, the store Id that I want and all the users if the have name tom for example.
how can I do that?
You should use a different structure for your database. NoSQL is more performant if you store data like you want to retrieve it.
But you can do what you want with something like that :
(It's just an example, you probably need to update and fix this code)
db.ref("offers").child(id).once("value", function(snapshot) {
var offerKey = snapshot.key;
var offerValue = snapshot.val();
snapshot.forEach(function(childSnapshot) {
var offerChildKey = childSnapshot.key;
var offerChildData = childSnapshot.val();
var quantity = offerChildData.quantity;
var store = offerChildData.store;
// Use quantity
Object.keys(store).forEach(function (storeKey) {
db.ref("store").child(storeKey).once("value", function(snapshot) {
var storeKey = snapshot.key;
var storeValue = snapshot.val();
var address = storeValue.address;
var users = storeValue.users;
// Use address
Object.keys(users).forEach(function (userKey) {
db.ref("users").child(userKey).once("value", function(snapshot) {
var userKey = snapshot.key;
var userValue = snapshot.val();
var name = userValue.name;
var lastname = userValue.lastname;
// Use name and lastname
}
});
}
});
});
}
Related
So I have an array which looks like this:
[
{ TransactionValues: '50.00' },
{ TransactionValues: '-77.43' },
{ TransactionValues: '-20.23' },
{ TransactionValues: '200.23' }
]
I am trying to find a way to target the monetary value and create a variable based on the sum of these. When I try to target the "50.00" for example I get "Undefined" and it's still an array.
I'm not exactly sure how I can target it specifically, is it possible? Any help would be appreciated
As per the comments here is the full code (be wary I'm still learning so it's not elegant):
var fs = require('fs');
var parse = require('csv-parse');
var transactionValues = []; //Need an array to hold transactions
var currentTrans = [];
var savingsTrans = [];
//constuctor for transactions
function addData (id, accountType, initiatorType, dateTime, transactions) {
var data = {
"AccountID" : id,
"AccountType" : accountType,
"InitiatorType" : initiatorType,
"DateTime" : dateTime,
"TransactionValues" : transactions
}
transactionValues.push(data); //should add a new line
}
function logTrans (accountType, transactions) {
if (accountType == "CURRENT") {
var cTrans = {
"TransactionValues" : transactions
}
currentTrans.push(cTrans);
}
else {
var sTrans = {
"TransactionValues" : transactions
}
savingsTrans.push(sTrans);
}
};
//parses the csv file, loops each row and adds it to the transactionValue array
var parser = parse({columns: true}, function (err, results) {
console.table(results);
for (const row of results) {
addData(row.AccountID, row.AccountType, row.InitiatorType, row.DateTime, row.TransactionValue );
logTrans(row.AccountType, row.TransactionValue);
}
console.log(transactionValues);
console.log(currentTrans);
console.log(savingsTrans);
});
fs.createReadStream(__dirname+'/testData/customer-1234567-ledger.csv').pipe(parser)
not completely following but at the end of the day you have an array like data below.
you can use filter to target the attribute you want.
you can use map to pull out just the values.
you can use reduce to sum them all up.
run the snippet below to see each step
const data = [
{ TransactionValues: '50.00', AccountType: 'CURRENT' },
{ TransactionValues: '-77.43', AccountType: null},
{ TransactionValues: '-20.23', AccountType: 'CURRENT' },
{ TransactionValues: '200.23', AccountType: null }
];
const CurrentTrans = data.filter((x) => x.AccountType === 'CURRENT');
const SavingTrans = data.filter((x) => x.AccountType !== 'CURRENT');
console.log('CurrentTrans');
console.log(CurrentTrans);
console.log('SavingTrans');
console.log(SavingTrans);
const CurrentTransValues = CurrentTrans.map((x) => parseFloat(x.TransactionValues));
const SavingTransValues = SavingTrans.map((x) => parseFloat(x.TransactionValues));
console.log('CurrentTransValues');
console.log(CurrentTransValues);
console.log('SavingTransValues');
console.log(SavingTransValues);
const TotalCurrentValues = CurrentTransValues.reduce((sum, x) => sum + x);
const TotalSavingValues = SavingTransValues.reduce((sum, x) => sum + x);
console.log('TotalCurrentValues');
console.log(TotalCurrentValues.toFixed(2));
console.log('TotalSavingValues');
console.log(TotalSavingValues.toFixed(2));
So I may have fixed it by using parseFloat in my addData and logTrans functions:
function addData (id, accountType, initiatorType, dateTime, transactions) {
var data = {
"AccountID" : id,
"AccountType" : accountType,
"InitiatorType" : initiatorType,
"DateTime" : dateTime,
"TransactionValues" : parseFloat(transactions)
}
transactionValues.push(data); //should add a new line
}
function logTrans (accountType, transactions) {
if (accountType == "CURRENT") {
var cTrans = parseFloat(transactions);
currentTrans.push(cTrans);
}
else {
var sTrans = parseFloat(transactions);
savingsTrans.push(sTrans);
}
};
Now that seems to of worked. So I can use the "Sum values of objects in array" as suggested before. Thank you everyone :)
Working on API response that gets user data from 10K ft system via API. The response looks like:
"data": [{
"id": 30000,
"display_name": "John Doe",
"email": "Johndoes#testmail.com",
},
I want to save this data in three different arrays for each response to be used later for looping through user id. I am not sure how to go about it. Below is the code I have worked on so far. I will appreciate any help here. Thanks
function getUsers() {
var auth = 'authentication'
var url = 'https://api.10000ft.com/api/v1/users?' + '&auth=' + auth;
var options = {
method: 'get',
headers: {
Authorization: 'Bearer ' + auth
}
};
};
let response = UrlFetchApp.fetch(url, options);
let json = JSON.parse(response);
};
var response = UrlFetchApp.fetch(url, options);
var json = JSON.parse(response);
var ids = [];
var display_names = [];
var emails = [];
function result(data) {
data.forEach(element => {
ids.push(element.id);
display_names.push(element.display_name);
emails.push(element.email);
});
return { "ids": ids, "display-names": display_names, "emails": emails };
}
console.log(result(data));
From what I understand...Maybe you're looking for something like this?
let json = JSON.parse(response);
let ids = [];
let dis_name = [];
let email = [];
for(let i = 0; i < json.length; i++){
ids.push(json[i].id);
dis_name.push(json[i].display_name);
email.push(json[i].email);
}
P.S Consider using let keyword instead of var.
if "data" contains more objects you need to loop through the data array and push the ids, display_names and emails in separate arrays. The below example will help you.
var data = [
{
"id": 30000,
"display_name": "John Doe",
"email": "Johndoes#testmail.com"
},
{
"id": 30001,
"display_name": "John Cena",
"email": "JohnCens#testmail.com"
},
{
"id": 30002,
"display_name": "John kabaraya",
"email": "Johnkabarayas#testmail.com"
}
]
var ids = [];
var display_names = [];
var emails = [];
function result(data) {
data.forEach(element => {
ids.push(element.id);
display_names.push(element.display_name);
emails.push(element.email);
});
return { "ids": ids, "display-names": display_names, "emails": emails };
}
console.log(result(data));
How do I create the data array from my second api call result into the format I want?
I have a code like this
var github = require('octonode');
var client = github.client();
var userName = "octocat";
var repoName = "";
var branchName = "";
var data = [];
var branches = [];
client.get('/users/'+userName+'/repos', {}, function (err, status, body, headers) {
body.forEach(function(obj) {
repoName = obj.name;
//==============================
client.get('repos/'+userName+'/'+repoName+'/branches', {}, function (errx, statusx, bodyChild, headersx) {
bodyChild.forEach(function(objChild) {
branchName = objChild.name;
});
});
});
});
I have received repoName and branchName data as well.
I want my data format like
How to use
data.push({
name: repoName,
branches: 'branchName loooping here for every repoName'
});
so branches repetition data can be contained in my branches tag
Thank you
I guess you can do something like this:
var data = [];
client.get('/users/'+userName+'/repos', {}, function (err, status, body, headers) {
body.forEach(function(obj) {
repoName = obj.name;
client.get('repos/'+userName+'/'+repoName+'/branches', {}, function (errx, statusx, bodyChild, headersx) {
let elem = {"name": repoName, "branches": []}; //create json object for each repo
bodyChild.forEach(function(objChild) {
elem.branches.push(objChild.name); //push all branchs to that elem
});
data.push(elem); // add the elem to the data array
});
});
});
So in this case data is an object, that has a property name which is string, and another property branches which is array. If you want to push data to the property branches you can just call the push() function on it.
Please check the example below:
let data = {
name: "repoName",
branches: [
{
name: "foo"
}
]
}
data.branches.push(
{
name: "bar"
}
);
console.log(data);
I got a multidimensional array where each array inside is a combination of all the user info (put in by the user)
I want the user to be able to modify his information, such as his name or phone number, so that the next time the user logs in, his new info is displayed.
The userList is saved on JSON, the idea would be for the changes to be saved and loaded from there.
Example:
if my array has
userList= JSON.parse(localStorage.getItem('userListLS')
if(userList == null) {
userList =
[
['Isaac', 'Garth', 'IsaacG11#email.com', 'Mazda']
['Matthew', 'Miller', 'mmiller21#mail.com', 'Volvo']
]
}
and lets say Isaac is logged in, and he wishes to change his name to Gabriel and change email to IsaacG21#email.com, so that the new array would be:
userList= [
['Gabriel', 'Garth', 'IsaacG21#email.com', 'Mazda']
['Matthew', 'Miller', 'mmiller21#mail.com', 'Volvo']
]
how could this be accomplished?
Only JS and HTML please.
The easiest approach would be to modify the data directly using index selectors:
This approach mutates the initial array instead of returning a new reference, which can lead to unwanted side effects.
function modifyData(data, userId, fieldId, newData) {
if(data[userId] && data[userId][fieldId]) {
data[userId][fieldId] = newData;
}
return data;
}
// example
var userList= [
['Isaac', 'Garth', 'IsaacG11#email.com', 'Mazda'],
['Matthew', 'Miller', 'mmiller21#mail.com', 'Volvo']
];
const FIELD_NAME_ID = 0;
const USER_ID = 0;
var modified = modifyData(userList, USER_ID, FIELD_NAME_ID, 'Morty')
console.log('initial', userList);
console.log('modified', modified);
An immutable approach would be:
function modifyData(data, userId, fieldId, newData) {
if(data && data[userId] && data[userId][fieldId]) {
var _data = data.slice();
var _user = data[userId].slice();
_user[fieldId] = newData;
_data[userId] = _user;
return _data;
}
return data;
}
// example
var userList= [
['Isaac', 'Garth', 'IsaacG11#email.com', 'Mazda'],
['Matthew', 'Miller', 'mmiller21#mail.com', 'Volvo']
];
const FIELD_NAME_ID = 0;
const USER_ID = 0;
var modified = modifyData(userList, USER_ID, FIELD_NAME_ID, 'Morty');
console.log('initial', userList);
console.log('modified', modified);
But you should consider changing your structure to a dictionary of objects:
{
user1: { name: 'Isaac', lastName: 'Garth' /* ... */ }
// ...
}
or an array of objects (but then you have to find the right user in the array:
[
{ name: 'Isaac', lastName: 'Garth' /* ... */ }
// ...
]
A good usecase for a Map:
const users = new Map(
userList.map(
( [first,name,email,car]) => [first, { first,name,email,car }]
)
);
So to change a certains users email:
users.get("Isaac").email = "test # gmail.com";
A few more usecases:
//set a whole user:
users.set("Jack", {
first:" Jack",
name:"Daniels",
email:"me#example.com",
car:"VW"
});
//get an array of users again
userList = [...users.values()];
The JSON of my firebase database looks like this:
{
"Films" :
[
{
"Title" : "Rear Window",
"Actors" : [ "James Stewart", "Grace Kelly", "Raymond Burr" ],
"Year" : "1954",
"Writer" : [ "John Michael Hayes (screenplay)", "Cornell Woolrich (short story)" ]
},
{
"Title" : "The Ring",
"Actors" : [ "Carl Brisson", "Lillian Hall-Davis", "Ian Hunter" ],
"Year" : "1927",
"Writer" : [ "Alred Hitchcock" ]
},
{
"Title" : "The Farmer's Wife",
"Actors" : [ "Jameson Thomas", "Lillian Hall-Davis", "Gordon Harker" ],
"Year" : "1928",
"Writer" : [ "1928" ]
}
]
}
I am building out my html based on the initial query from firebase like so:
// Initialize FireBase Database
firebase.initializeApp(config);
// Query the root of FireBase
var query = firebase.database().ref();
// Get a snapshot of all of the data
query.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var childData = childSnapshot.val();
buildFilms(childData);
});
});
// Build out the films
function buildFilms(films) {
for ( i = 0; i < films.length; i ++ ) {
var numOfActors = films[i].Actors.length,
filmDiv = document.createElement('div'),
filmTitle = document.createElement('h1');
filmTitle.innerHTML = films[i].Title;
filmDiv.setAttribute("id", "film" + i);
filmDiv.setAttribute("class", "film");
document.getElementById("wrapper").appendChild(filmDiv);
document.getElementById("film" + i).appendChild(filmTitle);
listActors(films, numOfActors);
showYear(films);
}
}
// List out Actors per film
function listActors(films, numOfActors) {
for ( subindex = 0; subindex < numOfActors; subindex ++ ) {
var actorTitle = document.createElement('h2');
actorTitle.innerHTML = films[i].Actors[subindex];
document.getElementById("film" + i).appendChild(actorTitle);
}
}
// List years per film
function showYear(films) {
var yearSpan = document.createElement('h4');
yearSpan.innerHTML = films[i].Year;
document.getElementById("film" + i).appendChild(yearSpan);
}
I would then like to use a basic html text input to repaint the dom on submit using Firebase's built in query, so something like this:
function runSearch(e) {
e.preventDefault();
var title = $('#title').val().toLowerCase();
$("#wrapper").empty();
setTimeout(function() {
query.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
// Need to narrow the films to the matching search input here
buildFilms(newFilteredData);
});
});
}, 1000)
}
I cannot figure out how to use the input to query my firebase data by "Title". Any help is much appreciated.
I hope firebase query orderBy startAt endAt will solve your requirement.
Note: This wont help you if you try to orderBy multiple fields, you'll have to write some other logic to achieve multiple fields orderBy.
Try the below code snippet. It'll filter the data for you!!
Hope this helps you!
var title = 'movie';
query
.orderByValue()
.startAt(title).endAt(title)
.on('value', function(snapshot) {
var movie = snapshot.val();
//do whatever you want.
});
For complete information on the Query related, please visit the below link
https://firebase.google.com/docs/reference/js/firebase.database.Query
This should work:
// Get the root of FireBase
var root = firebase.database().ref();
// Query the Films node under it
var query = root.child("Films");
// Get a snapshot containing the matching children from under Films
query.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
console.log(childSnapshot.val().Title);
});
});