How can I access nested data in Firebase with React? - javascript

I am working on building a simple app with React and Firebase - a way to manage income and expenditure, and my Firebase is set up with the following structure:
"cashbook" : {
"expenditure" : {
"expenditure-1" : {
"amount" : "500",
"category" : "insurance",
"date" : "date",
"name" : "Life Insurance",
"type" : "recurring"
}
},
"income" : {
"salary" : {
"amount" : "500",
"category" : "salary",
"date" : "date",
"type" : "recurring"
}
}
}
I have React set up and working perfectly with just the expenditure, using Re-base:
componentDidMount: function() {
// Two way data binding
base.syncState('cashbook/expenditure', {
context: this,
state: 'expenditure'
});
},
I can then reference using: this.state.expenditure
However, when I try to expand the app to access the Income data, things go pear shaped. I amended the componentdidmount to:
componentDidMount: function() {
// Two way data binding
base.syncState('cashbook', {
context: this,
state: 'cashbook'
});
},
And try to access with this.state.cashbook.expenditure and this.state.cashbook.income, but no joy, I get the error: Uncaught TypeError: Cannot read property 'expenditure' of undefined.
Not quite sure what to try, any pointers would be divine brown.
Thanks in advance :)

Turns out I was being a moron :)
I just needed to use syncstate on cashbook instead of cashbook/expenditure and call this.state.cashbook.expenditure.

Related

Mongo script to update an object if its a certain value

I am trying to update a document in Mongo if it has a certain value within a field.
{
"_id" : ObjectId("myObject"),
"source" : "BW",
"sourceTableName" : "myTable",
"tableName" : "tier",
"type" : "main",
"fieldMappings" : [
{
"sourceField" : "tier_id", <~~~~ If this is "tier_id", I want to change it to "trmls_id"
"reportingField" : "bw_id",
"type" : "integer",
"defaultMap" : {
"shouldErrorOnConvert" : false
}
}
]
}
I tried something like
db.getCollection('entityMap').update({"sourceTableName":"myTable"}, {"fieldMappings.0.sourceField":"trmls_id":{$exists : true}}, { $set: { "fieldMappings.0.sourceField": "tier_id" } })
and I think it is failing on the $exists parameter I am setting.
Is there a more cleaner/dynamic way to do this?
The whole query I am trying to formulate is
In the table myTable
I want to check if there is a sourceField that has the value tier_id
If there is tier_id, then change it to trmls_id
Otherwise do nothing
If there is a similar StackOverflow question that answers this, I am happy to explore it! Thanks!
There is a syntax mistake and you can use positional operator $ in update part because you have already selector field in query part,
db.getCollection('entityMap').update(
{
"sourceTableName": "myTable",
"fieldMappings.sourceField": "tier_id" // if this field found then it will go to update part
},
{
$set: {
"fieldMappings.$.sourceField": "trmls_id"
}
}
)

Dialogflow and Firebase - Iterate list of data

Making a chatbot that recommends a movie based on genre and other factors. Trying to iterate through an object retrieved from a firebase realtime database in DialogFlow. I'm using forEach but when triggered it displays "Not Available".
Preferably, the function would display a random item from the list but I have not reached that part yet - any advice on this too would be appreciated.
Below is my code.
function displayData(agent) {
return ref.orderByChild("genre1").equalTo("Comedy").on("child_added", function(snapshot) {
let obj = {};
obj = snapshot.val();
obj.forEach(function(childSnapshot) {
var childData = childSnapshot.val();
agent.add(childData.name);
});
});
}
Below is a sample database
{
"movies" : {
"movie1" : {
"genre1" : "Sci-Fi",
"genre2" : "Horror",
"name" : "Alien",
"rating" : 84,
"year" : 1979
},
"movie2" : {
"genre1" : "Comedy",
"genre2" : "Parody",
"name" : "Airplane",
"rating" : 97,
"year" : 1980
},
"movie3" : {
"genre1" : "Comedy",
"genre2" : "Teen",
"name" : "Superbad",
"rating" : 88,
"year" : 2007
}
}
}
The base problem is that the Dialogflow library requires you to return a Promise, however you're using the callback version of the call instead of the Promise version of the call. You need to change this to something more like
function displayData(agent) {
return ref.orderByChild("genre1").equalTo("Comedy").on("child_added")
.then( snapshot => {
// Do something with the snapshot
});
}
(You probably also want to use once("value") instead of on("child_added"), since you don't need updates to be sent in realtime.)
While the forEach() is probably working correctly, there is a minor problem that not all agents will return all the text that has been .add()ed. So you probably only want to call .add() once.
Since you really only want once of these children, picked randomly, you can just treat this as a JavaScript object if you have enough memory. So you could just get the keys with Object.keys(obj), pick one of the keys by random, and then get the full value of the result.

Highcharts returning error #15

I'm getting the following error:Highcharts error #15 I'm not quite sure I understand this error. I'm using Highcharts and making a $getJson() call to an API that returns data. The data returned looks like the following:
[ {
"timestamp" : 1503151200,
"price" : 4062.46,
"volume24h" : 123093.45
}, {
"timestamp" : 1503158400,
"price" : 3997.26,
"volume24h" : 120506.08
}, {
"timestamp" : 1503165600,
"price" : 4050.96,
"volume24h" : 114699.99
},
I have two functions that are looping and mapping the data. One for the 'timestamp' and 'price' and the other for the 'volume24'. The second function mapping the volume is causing error #15 and I'm not sure why. If I change the data coming from the API call then it won't be accurate. What am I doing wrong? Please see my complete code in the JsFiddle
You only need one function to loop through the data. Once I removed volumeData, put it's loop inside of mappedData and passed mappedData to the second data object in series, highCharts rendered as expected. This surprised me because the documentation example does it by passing two different objects.
series: [{
type: 'area',
name: `Bitcoin in USD`,
data: mappedData,
}, {
type: 'column',
data: mappedData,
yAxis: 1,
}]

Firebase - Retrieving data from pushed items

I'm stuck on this issue of how to retrieve pushed data from firebase. I've got it set up with authentication and I had two users push a little bit of data:
{
"deck" : {
"-JkpwAnieKjQVsdtPD4m" : {
"deckName" : "Deck 1",
"color" : "Red",
"user" : "simplelogin:1"
},
"-Jkq4unexm-qwhO_U2YO" : {
"deckName" : "Deck 2",
"color" : "Blue",
"user" : "simplelogin:1"
},
"-Jkq5-II1q5yM6w3ytmG" : {
"deckName" : "Deck 3",
"color" : "Green",
"user" : "simplelogin:6"
}
}
}
Then I run:
deckRef.once('value', function(dataSnapshot) {
console.log(dataSnapshot.val());
});
Which returns the 3 pushed with their keys generated by push().
It seems there there a way with firebase to say retrieve all color entries that are made by "simplelogin:1" (so Red and Blue) but I just can't figure it out.
You're probably looking for Firebase's queries, which allow you to:
deckRef.orderByChild('user').equalTo('simplelogin:1').on(...
Don't forget to add user to the .indexOn in your security rules.
See:
Firebase documentation on queries
Firebase documentation on indexing data
query your data like this
deckRef.orderByKey().once('child_added', function(dataSnapshot) {
console.log(dataSnapshot.val());
});
Note: orderByKey() works with child_added eventType
Reference

MongoDB and Mongoose: How to retrieve nested Object

I have the following documents in my mongodb collection:
{
"current" :
{
"aksd" : "5555",
"BullevardBoh" : "123"
},
"history" :
{ "1" : {
"deleted" : false,
"added" : false,
"date" : "21-08-2014"
}
},
{ "2" : {
"deleted" : false,
"added" : false,
"date" : "01-01-2013"
}
},
"_id" : ObjectId("53f74dad2cbfdc136a07bf16"),
"__v" : 0
}
I have multiple of these documents. Now I want to achieve two things with my Mongoose/Express API.
Query for all nested "current" in each document and retrieve them as JSON objects like such: {"aksd":"5555","BullevardBoh":"123"},{..},{..}.
Retrieve all history revisions (1,2...) where "date" is smaller than a given date.
As you can clearly see this is a kind of versioning I am trying to implement. I would also be interested if this kind of data structure will get indexed by MongoDB and if there is possibly a better way. (e.g. with arrays inside objects?)
This isn't working in MongoDB:
db.ips.findOne({current.aksd: {$exists:true}});
I think the quotes around the field are missing here:
db.ips.findOne({current.aksd: {$exists:true}});
This should work instead:
db.ips.findOne({"current.aksd": {$exists:true}});
While Ritesh's reply was a step in the right direction, I rather wanted to fetch the current object literal and its members inside the document not the whole document.
1.) Query for all nested "current" in each document
db.ips.find({"current":{$exists:true}}, {"current":1});
This is giving back all nested documents where the aksd literal is present:
{ "current" : { "aksd" : "5555", "BullevardBoh" : "123" }, "_id" : ObjectId("53f74dad2cb3dc136a07bf16") }
...
2.) Retrieving history revisions where date is smaller then a given date:
db.ips.find({"history.date": {$lt: "01-01-2014"}},{history:{$elemMatch:{date: {$lt:"01-01-2014"}}}});
Giving back the wanted nested date literal(s):
{ "historie" : [ { "date" : "01-01-2013", "added" : false, "deleted" : false } ], "_id" : ObjectId("53faf20f399a954b2b7736b6") }

Categories