Use variable to store "change.doc" path - javascript

I'm trying to use variable as a firestore doc path :
console.log(change.doc.data().m_1.name); <----- This work well !
a = 1;
let me = change.doc.data().m_+a; <----- But not that....
console.log(me.name);
How can i do that ?
Thank you in advance ! :)

You should use brackets when using dynamic property.
let me = change.doc.data()['m_' + a];

I think you want to build the name of the key as its own variable and use that to index into the object.
const a = 1;
const key = "m_" + a;
const me = change.doc.data()[key];

When you use your a variable in your example you're asking JS to add the number 1 to your functions output. This is not the correct way. You want to use a key to access the data from your data() functions return output as shown below.
change = {
doc: {
data: function() {
return {
m_1: {
name: "Mario",
occupation: "plumber",
siblings: 1,
age: 24
},
m_2: {
name: "Mike",
occupation: "developer",
siblings: 3,
age: "28"
}
}
}
}
}
console.log("Old way:" + change.doc.data().m_1.name);
const a = 1;
let me = change.doc.data()['m_' + a];
console.log("Desired way: " + me.name)
I have assumed a simple data structure derived from your question but I am not certain that it's what you get. But it might look a little like it.
EDIT awww.... The page didn't refresh and I did not see the two first answers :( well... at least we agree

Related

Updating Json Value with that of another Json

I want to update automatically the value of comments_list with the values in the comments JSON object
const tweet = JSON.stringify({"tweet_id":1,"created_at":"2022-06-28","comments_list":[]})
const comments = JSON.stringify({"tweet_id":1,"commenter_id": 2"commenter_first_name":"tito","commenter_username":"tito_lulu"})
The final output should look like this
{"tweet_id":1,"created_at":"2022-06-28","comments_list":[{"commenter_id": 2"commenter_first_name":"tito","commenter_username":"tito_lulu"}]}
I'd work with those strings in an object form, otherwise string-manipulation could be slow in some cases.
This is by no means the fastest solution but perhaps the idea behind it can be helpful.
const tweet = [{
"tweet_id": 1,
"created_at": "2022-06-28",
"comments_list": []
}]; // There could be many tweet objects so wrap it in an array
const comments = [{
"tweet_id": 1,
"commenter_id": 2,
"commenter_first_name": "tito",
"commenter_username": "tito_lulu"
},
{
"tweet_id": 1,
"commenter_id": 5,
"commenter_first_name": "me-too",
"commenter_username": "me294"
}
]; // Same here, could be many comments right?
let UpdatedTweets = [];
// There are faster ways to do this, but for your question
tweet.forEach((tweet, tweetIndex) => {
// Loop each tweet
let post = tweet;
comments.forEach((comment, commentIndex) => {
if (comment.tweet_id == tweet.tweet_id) {
// we have a match lets combine them
tweet.comments_list.push({
commenter_id: comment.comment_id,
commenter_first_name: comment.commenter_first_name,
commenter_username: comment.commenter_username
});
}
});
UpdatedTweets.push(post);
});
console.log(JSON.stringify(UpdatedTweets));
The general idea is:
Parse the JSON into JS objects
Update the target object with the complementary information
Stringify the target object into JSON (only if you need to, eg. send the data to some other machine)
In your case:
const tweet = JSON.stringify({"tweet_id":1,"created_at":"2022-06-28","comments_list":[]});
const comments = JSON.stringify({"tweet_id":1,"commenter_id": 2,
"commenter_first_name":"tito","commenter_username":"tito_lulu"});
let o_tweet = JSON.parse(tweet)
, o_comments = JSON.parse(comments)
;
if (Array.isArray(comments)) { // Test whether that is a single or multiple comments
comments.forEach( c => { o_tweet.comments_list.push(c); });
} else {
o_tweet.comments_list.push(o_comments);
}
console.log(o_tweet);
// Only if needed:
// let newtweet = JSON.stringify(o_tweet)

Preventing duplicate objects from being added to array?

I am building a little shop for a client and storing the information as an array of objects. But I want to ensure that I am not creating "duplicate" objects. I have seen similar solutions, but perhaps it is my "newness" to coding preventing me from getting the gist of them to implement in my own code, so I'd like some advice specific to what I have done.
I have tried putting my code in an if look, and if no "part", my variable looking for part number, exists in the code, then add the part, and could not get it to function.
Here is the function I am working on:
function submitButton(something) {
window.scroll(0, 0);
cartData = ($(this).attr("data").split(','));
arrObj.push({
part: cartData[0],
description: cartData[1]
});
}
arrObj is defined as a global variable, and is what I am working with here, with a "part" and a "description", which is the data I am trying to save from elsewhere and output to my "#cart". I have that part working, I just want to ensure that the user cannot add the same item twice. (or more times.)
Sorry if my code is shoddy or I look ignorant; I am currently a student trying to figure these things out so most of JS and Jquery is completely new to me. Thank you.
You can create a proxy and use Map to hold and access values, something like this
let cart = new Map([{ id: 1, title: "Dog toy" }, { id: 2, title: "Best of Stackoverflow 2018" }].map(v=>[v.id,v]));
let handler = {
set: function(target,prop, value, reciver){
if(target.has(+prop)){
console.log('already available')
} else{
target.set(prop,value)
}
},
get: function(target,prop){
return target.get(prop)
}
}
let proxied = new Proxy(cart, handler)
proxied['1'] = {id:1,title:'Dog toy'}
proxied['3'] = {id:3,title:'Dog toy new value'}
console.log(proxied['3'])
Assuming the 'part' property is unique on every cartData, I did checking only based on it.
function submitButton(something) {
window.scroll(0, 0);
cartData = ($(this).attr("data").split(','));
if(!isDuplicate(cartData))
arrObj.push({
part: cartData[0],
description: cartData[1]
});
}
const isDuplicate = (arr) => {
for(obj of arrObj){
if(arr[0] === obj.part)
return true;
}
return false;
}
If you want to do the checking on both 'part' and 'description' properties, you may replace the if statement with if(arr[0] === obj.part && arr[1] === obj.description).
Thanks everyone for their suggestions. Using this and help from a friend, this is the solution that worked:
function submitButton(something) {
window.scroll(0,0);
cartData = ($(this).attr("data").split(','));
let cartObj = {
part: cartData[0],
description: cartData[1],
quantity: 1
}
match = false
arrObj.forEach(function(cartObject){
if (cartObject.part == cartData[0]) {
match = true;
}
})
console.log(arrObj);
if (!match) {
arrObj.push(cartObj);
}
Okay, you have multiple possible approaches to this. All of them need you to specify some kind of identifier on the items which the user can add. Usually, this is just an ID integer.
So, if you have that integer you can do the following check to make sure it's not in the array of objects:
let cart = [{ id: 1, title: "Dog toy" }, { id: 2, title: "Best of Stackoverflow 2018" }];
function isInCart(id) {
return cart.some(obj => obj.id === id);
}
console.log(isInCart(1));
console.log(isInCart(3));
Another approach is saving the items by their id in an object:
let cart = { 1: { title: "Dog toy" }, 2: { title: "Best of Stackoverflow 2018" } };
function isInCart(id) {
if(cart[id]) return true;
return false;
}
Try to use indexOf to check if the object exists, for example:
var beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];
console.log(beasts.indexOf('aaa'));
// expected output: -1

JAVASCRIPT object to array conversion

I search on stackoverflow before post my question, but I didn't find any solution. I have an object like this :
"{"COURRIERS":
{"05. Juridique":
[{"res_id":100,"type_label":"Plainte","subject":"test23","doctypes_first_level_label":"COURRIERS","doctypes_second_level_label":"05. Juridique","folder_level":2}]
}
}"
And I need to access it like an array, in order to get the information like res_id etc..
How can I do this ?
Thanks in advance
Assuming that you won't have more than one object/array in each layer, this should get you what you need.
let obj = {
"COURRIERS": {
"05. Juridique": [{
"res_id": 100,
"type_label": "Plainte",
"subject": "test23",
"doctypes_first_level_label": "COURRIERS",
"doctypes_second_level_label": "05. Juridique",
"folder_level": 2
}]
}
}
let folder = Object.keys(obj)[0]
let type = Object.keys(obj[folder])[0]
let result = obj[folder][type][0]
console.log(result)
You can gain access to the data in multiple ways. The following below will help clarify some of the way you can access some of the data.
myObj.type = "Dot syntax";
myObj.type = "Dot syntax";
myObj["date created"] = "String with space";
myObj[str] = "String value";
myObj[rand] = "Random Number";
myObj[obj] = "Object";
myObj[""] = "Even an empty string";
For your problem you can use the following
var x = {
"COURRIERS":{
"05. Juridique":[
{
"res_id":100,
"type_label":"Plainte",
"subject":"test23",
"doctypes_first_level_label":"COURRIERS",
"doctypes_second_level_label":"05. Juridique",
"folder_level":2
}
]
}};
console.log(x['COURRIERS']['05. Juridique'][0].res_id)
Something like that ?
(I insert the data inside a variable and print the wanted result with key index)
let obj = {
"COURRIERS":{
"05. Juridique":[
{
"res_id":100,
"type_label":"Plainte",
"subject":"test23",
"doctypes_first_level_label":"COURRIERS",
"doctypes_second_level_label":"05. Juridique",
"folder_level":2
}
]
}
};
console.log(obj["COURRIERS"]["05. Juridique"][0]["res_id"]);
EDIT
You want to acess it with variable.
For avoid bug, I strong recommend you to check if the variable value key exist in the array/object like :
let folder = 'COURRIERS';
if(folder.indexOf(data) >= 0) { // folder.indexOf(data) = 0
// ... finish the job here :)
}
// indexOf return -1 if the value is not found

Appending to JS object

Hope this isn't too much of a repeating question, I've checked around seen similar but can't seem to solve my issue.
I have a JS object:
var option1Data = {
option: 'Yes',
numberOfPeople: 3,
gender: {} ,
region: {}
};
I want to check if an item is in gender, if not add and set to 1 else increment into. Note that appending it in is important.
Can someone kindly tell me whats wrong:
var input = 'female'; //for purposes of this example
var processGender = function(input) {
if(option1Data['gender'].hasOwnProperty(input)) {
option1Data['gender'][input]++;
}else {
option1Data['gender'][input] = 1;
}
};
User.find({_id: item['userID']}, {gender: 1, country:1}, function(req, foundUser) {
processGender(foundUser[0]['gender']);
});
You can't guarantee property order if using an object, you can see this stackoverflow answer for that :
Does JavaScript Guarantee Object Property Order?
So appending is out of the question for the structure you're using.
But maybe something like below would work for you :
var maleGenderObject= { gender : "male" , count : 0 };
var femaleGenderObject = {gender : "female" , count : 0 };
var option1Data = { option: 'Yes',
numberOfPeople: 3,
gender: [] ,
region: {} };
Then when adding , you can do something like :
var input = "female";
//Nothing exists at the moment, so add the proper object, I added both since there are only two, but you can modify for more genders, but logic will be a bit more complex
if ( option1Data.gender.length == 0 ){
if (input == "female" ){
option1Data.gender.push(femaleGenderObject);
option1Data.gender.push(maleGenderObject);
}
else {
option1Data.gender.push(maleGenderObject);
option1Data.gender.push(femaleGenderObject);
}
}
//If both gender objects exist, determine which one you want, and increment its count
if (option1Data.gender[0].gender == input){
option1Data.gender[0].gender.count++;
}
else {
option1Data.gender[1].gender.count++;
}
This definitely can be optimized, but it's really two variables so I think simple straightforward is better in this case
Another way is to have your gender objects have an order property, and you can use that.
Your code is working fine:
var option1Data = {
option: 'Yes',
numberOfPeople: 3,
gender: {},
region: {}
},
input = 'female';
if (option1Data['gender'].hasOwnProperty(input)) {
option1Data['gender'][input]++;
} else {
option1Data['gender'][input] = 1;
}
document.write('<pre>' + JSON.stringify(option1Data, 0, 4) + '</pre>');

JS object behavior is different when I change the property value

I'm completely new to JS and trying to learn on my own. Using below code -
var me = {
name: {first:"justin"}
},
name = me.name;
name = {first: "alexis"};
Why would document.write(me.name.first + "</br>"); return justin?
and
why would document.write(this.name.first); doesn't return anything?
Please can you explain me?
Thanks,
Me
Just change the variable name name to other string, for example: n. Everything will work perfect.
var me = {
name: {first:"justin"}
},
n = me.name;
n = {first: "alexis"};
The reason is this.name.first will refer to window.name.first. But window.name has special usage in javascript and has to be a string.

Categories

Resources