equalTo returning null from Firebase? - database

In my React Native App, I currently am trying to pull all items that have the selected property set to "true" from the database. However, when I log the results of this query, they are all being returned as null (even though expected response should be returning two objects). My relevant code as well as Firebase structure are included below, please let me know if you spot anything.
const rootRef = new Firebase(`${ config.FIREBASE_ROOT }`)
var queryRef = rootRef.orderByChild("items/selected");
var solution = queryRef.equalTo("true").once('value', function(snap) {
console.log(snap.val())
});
Firebase JSON:
"items":
[
{
"title":"ball",
"selected": "false"
},
{
"title":"dog",
"selected": "true"
},
{
"title":"phone",
"selected": "false"
},
{
"title":"cup",
"selected": "true"
}
],

When you run an Firebase query on a location, it takes each child node under that location and then evaluates the condition you specify. If you take each child under items, you'll see there is no path items/selected under there.
You query is instead:
var itemsRef = rootRef.child("items");
var queryRef = itemsRef.orderByChild("selected");

You should use
where("selected" = true)
instead of equalTo()

Related

React update values only once

I have a newb question :)
I have a modal that opens in React Native with a dropdown select that requires values. I want to calculate the values whenever the modal opens.
let pickupTime; // Set a value that can be overwritten. I'm not using State because I want this value to change whenever I open the modal again.
const pickupTimeOptions = useRef([{ label: "", value: "" }]); // A ref to store the values
useEffect(() => {
const pickup_hours_today = business.pickup_hours_today; // Array of strings I pass to the modal.
console.log("pickup_hours_today", pickup_hours_today);
const options = pickup_hours_today.map((time) => {
return {
label: time,
value: time,
};
});
pickupTimeOptions.current = options;
}, [business.pickup_hours_today]);
console.log("pickupTimeOptions", pickupTimeOptions); // Let's see if we got it
The problem is that the ref never updates. The log prints this:
pickupTimeOptions Object {
"current": Array [
Object {
"label": "",
"value": "",
},
],
}
pickup_hours_today Array [
... // the string array of hours
]
Should be updating the ref
pickupTimeOptions Object {
"current": Array [
Object {
"label": "",
"value": "",
},
],
}
pickup_hours_today Array [
...
]
Should be updating the ref
What am I doing wrong? Should I handle this differently? I don't mind using state, but when I tried, it kept updating it whenever I selected a different values with the dropdown picker.
If you look at the order of console logs, it'll explain what's happening.
This is printed first, meaning calculation in useEffect hasn't happened yet
console.log("pickupTimeOptions", pickupTimeOptions); // Let's see if we got it
According to the documentation useEffect is only called after the render. You need to do the calculation before or during the render cycle.
You can use useMemo which is executed during rendering. Refer to the documentation for more details
Your updated code should look something like this
let pickupTime; // Set a value that can be overwritten. I'm not using State because I want this value to change whenever I open the modal again.
const pickupTimeOptions = useMemo(() => {
const pickup_hours_today = business.pickup_hours_today; // Array of strings I pass to the modal.
console.log("pickup_hours_today", pickup_hours_today);
const options = pickup_hours_today.map((time) => {
return {
label: time,
value: time,
};
});
return options;
}, [business.pickup_hours_today]);
console.log("pickupTimeOptions", pickupTimeOptions); // Let's see if we got it

How to write a test for nested JSON response from enterprise application

I'm trying to use Postman as a test tool to validate that our customers all have a mailing address in our master system. I'm having trouble drilling down into the JSON due to its structure. Each response is an array structure with a single "node" that has no "head attribute" to address.
Example JSON:
[
{
"ID": "cmd_org_628733899",
"organization": {
"name": "FULL POTENTIAL",
"accountStatusCode": "1",
"accountStatusDescription": "OPEN"
},
"location": [
{
"locality": "LITTLE ROCK",
"locationType": "MAILING"
},
{
"locality": "BIG ROCK",
"locationType": "LOCATION"
}
]
}
]
Test code as it exists:
pm.test("Check for a Mailing Address", function () {
// Parse response body
var jsonData = pm.response.json();
// Find the array index for the MAILING Address
var mailingLocationIndex = jsonData.location.map(
function(filter) {
return location.locationType;
}
).indexOf('MAILING');
// Get the mailing location object by using the index calculated above
var mailingLocation = jsonData.location[mailingFilterIndex];
// Check that the mailing location exists
pm.expect(mailingLocation).to.exist;
});
Error message: TypeError: Cannot read property 'map' of undefined
I understand that I have to iterate to node(0) in the outer array and then drill into the nested location array to find an entry with a locationType = Mailing.
I can't get past the outer array. I'm new to JavaScript and JSON parsing - I am a COBOL programmer.
Knowing nothing else, I would say you mean this
pm.test("Check for a Mailing Address", function () {
var mailingLocations = pm.response.json().location.filter(function (item) {
return item.locationType === 'MAILING';
});
pm.expect(mailingLocations).to.have.lengthOf(1);
});
You want to filter out all the locations that have a MAILING type and there should be exactly one, or at least one, depending.
Whether pm.response.json() actually returns the object you show in your question is impossible to say from where I'm standing.
In modern JS, the above is shorter:
pm.test("Check for a Mailing Address", function () {
var mailingLocations = pm.response.json().location.filter(item => item.locationType === 'MAILING');
pm.expect(mailingLocations).to.have.lengthOf(1);
});

Javascript looping through an object

I have an object which is given back through my REST API and I need to iterate through it for synchronizing a DB. So the object contains another object called tables. The tables object has different arrays with table names and their key value pairs.
I could not loop through the tables object about two days whatever I did and it is really annoying getting null or undefined values back.
For example I tried iterating through the table array with the JavaScript function object.forEach((article)=>console.log(article.id,article.name));
const obj = response.content.tables.article;
function findArticles(obj) {
obj.forEach((article)=>console.log(article.id,article.name));
}
I can't get any value back. When I try to console.log(response.content); it shows me everything. As soon as I try to output response.content.tables it says undefined.
This is the structure of the object response.content:
{
"status": "1",
"message": "sync out request successfull",
"tables": {
"article": [
{
"id": 1,
"name": "baseball"
},
{
"id": 2,
"name": "truck"
},
],
"food": [],
"animals: []
}
}
Try converting the response to an object using JSON.parse(xyz) before attempting to get the properties.
var xyz = '{ "status": "1", "message": "sync out request successfull", "tables": { "article": [{"id": 1,"name": "baseball"},{"id": 2,"name": "truck"}],"food": [],"animals": []}}'
var obj = JSON.parse(xyz);
$(obj.tables).each(function (ix, el) {
console.log(el)
});
I solved it like this:
var obj = response.content;
var JSON = JSON.parse(obj);
var articleTable = JSON.tables.article;
articleTable.forEach((article)=>console.log(article.id,article.name));
After I parsed the response.content object to JSON it was available to access the nested objects as 'tables' and 'article'. After passing the article object with the articleTable variable to the forEach it has been possible to access each elements. Now I get results.
I really appreciate your help
T3.0 it wasn't able to solve the problem without you.

How add or delete an item from a tab in a hook?

I'm new with hooks and I would like to add or delete an item from my tab.
I don't know how to do it because this tab is an attribute of my hook tab.
const [questionResponses, setResponses] = useState(null);
I tried this fix but the syntax don't work :
setResponses( questionResponses[idQuestion].responses => [...questionResponses[idQuestion].responses,{
response_text: itemValue,
response_type: type,
}]);
I tried to use concat(), but it's freezing when the tab responses is not empty:
setResponses({
...questionResponses[idQuestion].responses, [idQuestion]: questionResponses[idQuestion]['responses'].concat([{
response_text: itemValue,
response_type: type,
}])
});
My tab have this structure:
[
{
"question_id": 1,
"question_text": "Best time of day",
"responses": [
{
"response_id": 33,
"response_text": "Morning",
"response_type": "radio"
}
]
},
{
"question_id": 2,
"question_text": "I heard about Marie-France Group via",
"responses": []
},...]
Could you help me please ? I don't know how to do it
Please see the code I added https://codesandbox.io/s/mystifying-liskov-quv5m.
Use spread operator for adding value in the existing array.
function addRespone() {
setResponses([...responses, { name: response }]);
}
For removal filter the exsiting array to remove the intended item.
function deleteResponse(itemIndex) {
const newResponses = responses.filter((item, index) => index !== itemIndex);
setResponses(newResponses);
}
Check codesandbox link for complete code.

Querying Firebase based on time

I am trying to query my Firebase based on time limits. I am following this blog post with this attached jsFiddle.
The issue is that I am getting a blank firebaseArray back.
var currentTime = (new Date).getTime();
var twentyFoursHoursAgo = currentTime - 86400000;
//scoresRef is defined as new Firebase(http://myfirebase.firebaseio.com/scores)
scoresRef.on('value', function (dataSnapshot) {
var summaryScores = $firebaseArray(scoresRef.orderByChild('timestamp').startAt(twentyFoursHoursAgo).endAt(currentTime));
$scope.summaryScores = summaryScores;
console.log(summaryScores);
}
The idea is that as users add more scores, the array will change. Then I can do different data manipulation on it (like average, etc). That way, there can be a running 24 hour average displayed on the app.
This is what the data looks like in Firebase:
What am I doing wrong? I know the data is in there.
Not sure if this answer your question, but it seems the best I can do is show you something that works.
Querying for a range of timestamps
I added this data structure:
{
"-Jy5pXbn5RpiK1-5z07O": {
"timestamp": 1441076226561
},
"-Jy5pZJsYvsmv_dMtCtn": {
"timestamp": 1441076173543
},
"-Jy5paWbkU6F8C6CEGpj": {
"timestamp": 1441076181550
},
"-Jy5pbc0pJ1I5azenAi5": {
"timestamp": 1441076247056
},
"-Jy5pfnMDKExW2oPf-D-": {
"timestamp": 1441076204166
},
"-Jy5pgk55ypuG9_xICq-": {
"timestamp": 1441076268053
},
"-Jy5phVgU2hDE_izcR8p": {
"timestamp": 1441076271163
},
"-Jy5pilBteGhu05eMWQI": {
"timestamp": 1441076215315
}
}
And then query with this code:
var ref = new Firebase('https://stackoverflow.firebaseio.com/32321406');
var startAt = 1441076265715;
var endAt = startAt + 15000;
var query = ref.orderByChild('timestamp')
.startAt(startAt)
.endAt(endAt);
query.on('value', function(snapshot) {
console.log(snapshot.val());
});
Which outputs:
{
-Jy5pgk55ypuG9_xICq-: {
timestamp: 1441076268053
},
-Jy5phVgU2hDE_izcR8p: {
timestamp: 1441076271163
}
}
And a warning that I should add an indexing rule for timestamp.
jsbin: http://jsbin.com/qaxosisuha/edit?js,console
Binding a collection of data from Firebase to AngularJS
If you're trying to bind the query results to an AngularJS view, you do this by:
$scope.items = $firebaseArray(query);
When using AngularFire don't try to use console.log to monitor what is going in. Instead add this to your HTML:
<pre>{{ items | json }}</pre>
This will print the items and automatically update as the data is asynchronously loaded and updated.
Note that this may be a good time to go through Firebase's AngularFire programming guide, which explains this last bit and many more topics in a pretty easy to follow manner.

Resources