How can i manipulate an object while inside of a loop - javascript

So i m trying to manipulate the object while going through the loop.
Well, its not working.. How can i make it work so the const patient has the property lastActivity inside of the this.model array?
javascript:
for (const item of data) {
const patient = this.model.find(
x => x.linkedUserId === item.userId
);
if (patient) {
patient.lastActivity = item.lastUploadDate;
}
}

The patient in the array itself is not updated, to make sure you are not updating a separate patient you can use a for-loop so that you definitely update the patient in the array.
for (const item of data) {
for (let i = 0; i < this.model.length; i++) {
if (this.model[i].linkedUserId === item.userId) {
this.model[i].lastActivity = item.lastUploadDate;
break;
}
}
}

If you can store data in this.model as an object you can update it easily. Consider the following model data.
{
"abcd": { linkedUserId: "abcd", name: "user1" },
"efgh": { linkedUserId: "efgh", name: "user2" },
}
Now you can update the model by doing the following.
for (const item of data) {
this.model[item.userId].lastActivity = item.lastUploadDate;
}
To get model in the form of an array you can do const model = Object.values(this.model);.

Related

How to check nested JSON property and value exist in JavaScript?

I am getting below JSON as API response. Response contains multiple session node, each session node contains multiple event node. I would like to identify the first "SEARCH" event ("type") in any of the session ascending. If the "SEARCH" event is found, then, from the particular event, I need to get the "Interest" node value.
var guestJson = await response.json();
for(var property in guestJson)
{
if(property === "sessions")
{
var sessionObj = JSON.parse(JSON.stringify(guestJson[property]))
for(var i=0; i< sessionObj.length; i++)
{
var eachSessionObj = JSON.parse(JSON.stringify(sessionObj[i]))
for(var sessionProperty in eachSessionObj)
{
if(sessionProperty === "events")
{
console.log("Events Found")
//console.log(sessionProperty)
}
}
}
}
}
I am able to do with for loop like below. But i think it's not the effective way of doing that
Below is the JSON structure
{
"firstName":"fn",
"lastName":"ln",
"gender":"male",
"sessions":[
{
"currency":"USD",
"events":[
{
"type":"SEARCH",
"status":"PROCESSED",
"arbitraryData":{
"interest":"Health"
}
},
{
"type":"CHECK",
"status":"PROCESSED",
"arbitraryData":{
"interest":"Dental"
}
}
]
},
{
"currency":"USD",
"events":[
{
"type":"SEARCH",
"status":"PROCESSED",
"arbitraryData":{
"interest":"Health"
}
},
{
"type":"CHECK",
"status":"PROCESSED",
"arbitraryData":{
"interest":"Dental"
}
}
]
}
]
}
You could try a function like this:
function extractInterest(guestJson) {
// Get all sessions or else get an empty array
const sessions = guestJson.sessions || [];
// Filter all sessions with events
const interest = sessions.filter(session => session.events)
.flatMap(session => session.events) // Maps all the events to a single list
.filter(event => event.type === "SEARCH") // Filter only the events with type "SEARCH"
.map(event => event.arbitraryData.interest); // Extract the interest from each event
return interest; // return the list of interests
}
When applied to your example JSON, this returns an array of interests like this:
[ 'Health', 'Health' ]

How would I be able to return more than one object based on user input amount

Let's say PackInput is an array input.
What I'd like to do's return a dynamic amount of objects depending on how large the input array PackInput is.
For example: if PackInput is [4,5,6], then I'd like three objects returned for each ItemID.
For example: return {... ItemID: 4 ...}, return {... ItemID: 5 ...}, return {... ItemID: 6 ...}.
My current code below is only grabbing the first item of the array instead of all of them and I'm not sure why. I've turned my wheels on this for so long and now I've hit a wall. What am I doing wrong?
for(let i = 0; i < PackInput.length; i++) {
return {
TimestampUTC: Date.now(),
Payload: {
ItemID : PackInput[i]
}
}
}
Updated:
let array = PackInput.map((items) => ({
TimestampUTC: Date.now(),
Payload: {
ItemID : items
}
})
);
let objects = array.reduce(function(target, key, index) {
target[index] = key;
return target;
})
return objects;
You can use the map method to achieve what you want
return PackInput.map((element) => ({
TimestampUTC: Date.now(),
Payload: {
ItemID : element
}
}))
A return statement ends the execution of a function, and returns control to the calling function/upper scope.
Update on object:
const object = PackInput.reduce(function(previousValue, currentValue, index) {
return {
...previousValue,
[index]: currentValue
}
}, {})
You need to provide an empty object as 2nd argument for the reduce function.
You can return an array/object. The problem is that you can call return only once in a function and as soon as a function reaches return it would be returned to the caller scope. You can use the loop to create the array/object and then return the final value:
let array = [];
for(let i = 0; i < PackInput.length; i++) {
array.push({
TimestampUTC: Date.now(),
Payload: {
ItemID : PackInput[i]
}
});
}
return array;

I'm unable to manipulate data stored in an array from firebase

I'm getting data from firebase with the following compound query:
filterItineraries(filters: any): any {
this.allItineraries = [];
this.filteredItineraries = [];
for ( let i = 0; i < filters.dateRange.length; i ++) {
const query = this.dataSvc.getAllItineraries()
.where('destination', '==', filters.destination)
.where('dateRange', 'array-contains', filters.dateRange[i]);
query.onSnapshot(itineraryListSnapshot => {
itineraryListSnapshot.forEach(snap => {
this.allItineraries.push({
id: snap.id,
activities: snap.data().activities,
destination: snap.data().destination,
startDate: snap.data().startDate,
endDate: snap.data().endDate,
jobId: snap.data().jobId,
userId: snap.data().userId
});
});
});
}
I initially declared the array in which I'm storing the objects like this:
private matchItinerary: allItineraries = [];
then I tried declaring like this:
private allItineraries: { 'id': string, 'activities': any[], 'destination': string, 'startDate': string, 'endDate': string, 'jobId': string, 'userId': string }[] = [];
still did not work.
The issue is caused because of the limitations of the queries in firebase. As a result I end up with duplicate records that I need to remove. After I retrieve the data from firebase the array functions aren't recognized. I can't get elements, I can't use .length...it = 0. When I console.log(typeof allItineraries) it displays object.
for (let i = 0; i < allItin.length; i++) {
for (let k = 0; k < allItin.length - 1; k++) {
if (allItin[k].id !== allItin[k + 1].id) {
console.log('inside if', allItin[k + 1].id);
this.filteredItineraries[k] = allItin[k + 1];
}
}
}
The data will show in the UI, but I can't perform any array operations in my code. If I just do a console.log(allItineraries) it will in fact show all of the data but what I need to do is filter the data and it won't let me perform any Array operations.
I've been working on this for a few weeks now and posted numerous times to no avail. I don't know what to do at this point...nothing seems to work. I don't know if I'm declaring the array wrong. The data can be seen but not manipulated the way normal arrays allow.
Save the data in a local variable and filter in inside the snapshot callback.
filterItineraries(filters: any): any {
for ( let i = 0; i < filters.dateRange.length; i ++) {
const query = this.dataSvc.getAllItineraries()
.where('destination', '==', filters.destination)
.where('dateRange', 'array-contains', filters.dateRange[i]);
query.onSnapshot(itineraryListSnapshot => {
const allItineraries = [];
const filteredItineraries = [];
itineraryListSnapshot.forEach(snap => {
allItineraries.push({
id: snap.id,
activities: snap.data().activities,
destination: snap.data().destination,
startDate: snap.data().startDate,
endDate: snap.data().endDate,
jobId: snap.data().jobId,
userId: snap.data().userId
});
// filter your array here
// save it in state or assign it to filteredItineraries[]
// doing the following won't force state re-render
// this.filteredItineraries = allItineraries.filter(...);
});
});
}

Looping through an array of objects and find a specific key

I have an array of objects which looks like
data =
[
{
"AccountType":"Client",
"DeploymentList":
{
"-L3y8Kpl5rcvk-81q004":
{
"DeploymentKey":"-L3y8Kpl5rcvk-81q004",
"DeploymentName":"Testing 3"
}
}
},
{
"AccountType":"Client",
"DeploymentList":
{
"-L3yGFxXQ8XbeK8b2GSF":
{
"DeploymentKey":"-L3yGFxXQ8XbeK8b2GSF",
"DeploymentName":"Testing 1"
}
}
}
]
I want to loop through this data and want to find a string. In this data, I want to find
What I have tried so far is
for (let d of this.data) {
for(let a of d.DeploymentList){
if(a.$key==="-L3y8Kpl5rcvk-81q004"){
// Inside the condition
}
}
But it is not working. How I can achieve this ?
You can check if key exists as follows,
for (let d of this.data) {
for(let a of d.DeploymentList){
if(a["-L3y8Kpl5rcvk-81q004"]){
// Inside the condition
}
}
It depends on what you want to do. If you're just trying to find the deployment list item you can do it easily with find
var item = data.find(item => item.DeploymentList["-L3y8Kpl5rcvk-81q004"]);
This will give you the item from your data array with that particular DeploymentList item.
var data =
[
{
"AccountType":"Client",
"DeploymentList":
{
"-L3y8Kpl5rcvk-81q004":
{
"DeploymentKey":"-L3y8Kpl5rcvk-81q004",
"DeploymentName":"Testing 3"
}
}
},
{
"AccountType":"Client",
"DeploymentList":
{
"-L3yGFxXQ8XbeK8b2GSF":
{
"DeploymentKey":"-L3yGFxXQ8XbeK8b2GSF",
"DeploymentName":"Testing 1"
}
}
}
];
var item = data.find(item => item.DeploymentList["-L3y8Kpl5rcvk-81q004"]);
console.log(item);

Firebase orderByChild Ignored

How do I sort the following structure in Firebase by sortOrder?
categories {
{
"b": {
"name": "Banana",
"sortOrder": 2
},
"a": {
"name": "Apple",
"sortOrder": 1
}
}
}
From the documentation it looks as simple as:
ref('categories').orderByChild('sortOrder').once('value') ...
However, the first node returned is banana. It doesn't matter what string value I use. For example, the following returns the same results:
ref('categories').orderByChild('xxx').once('value') ...
Full function:
public list(): Observable<Category[]> {
let ref = firebase.database().ref('categories').orderByChild('sortOrder');
return Observable.fromPromise(<Promise<any>>ref.once('value'))
.flatMap(snapshot => {
let objects = snapshot.val();
let categories: Array<Category> = new Array();
for (let key in objects) {
let category: Category = objects[key];
category.code = key;
categories.push(category);
}
return Observable.of(categories);
}
);
}
The problem is that when you access the children via the snapshot's value's keys, the order is indeterminate.
You need to use the snapshot's forEach method:
return Observable.fromPromise(<Promise<any>>ref.once('value'))
.flatMap(snapshot => {
let categories: Array<Category> = new Array();
snapshot.forEach(childSnapshot => {
let category: Category = childSnapshot.val();
category.code = childSnapshot.key;
categories.push(category);
});
return Observable.of(categories);
}
);
Also, you could just use map and return categories.

Categories

Resources