Having issue with getting value from object variable. No errors showing - javascript

I created an array called animals containing two objects. I want to get a value from the name variable in the object animals and insert that value in a return statement in the map method. I used ${} to access the variable.
const Animals = [{
name: "Lion",
type: "Carnivore",
},
{
name: "Cow",
type: "Herbivore",
},
];
window.addEventListener("DOMContentLoaded", function() {
let display = Animals.map(function(item) {
return '<h1>${item.name}</h1>';
});
console.log(display);
});
Now I'm supposed to get in the console an array of two items containing the values of the variables -- the result should look like this ['<h1>Lion</h1>', '<h1>Cow</h1>']. But instead I get this ['<h1>${item.name}</h1>', '<h1>${item.name}</h1>']. As you can clearly see, for some reason the ${} was unable to access the variable and get the value. I don't know why this's happening. Console log shows no errors. Plz help me resolve this issue. Thanks in advance.

Check in your code instead of:
'<h1>${item.name}</h1>'
Should be:
`<h1>${item.name}</h1>`
Here is the documentation for Template literals (Template strings)
Demo:
const Animals = [{
name: "Lion",
type: "Carnivore",
},
{
name: "Cow",
type: "Herbivore",
},
]
const display = Animals.map(({ name }) => `<h1>${name}</h1>`)
console.log(display)

Variables inside ${...} structures are template/string literals syntax but in order for them to work they need to be enclosed with backticks instead of single/double quotes.
const animals=[{name:"Lion",type:"Carnivore"},{name:"Cow",type:"Herbivore"}];
window.addEventListener("DOMContentLoaded", function() {
const display = animals.map(function(item) {
return `<h1>${item.name}</h1>`;
});
console.log(display);
});

const Animals = [{
name: "Lion",
type: "Carnivore",
},
{
name: "Cow",
type: "Herbivore",
},
];
window.addEventListener("DOMContentLoaded", function() {
let display = Animals.map(function(item) {
return '<h1>'+item.name+'</h1>';
// return `<h1>${item.name}</h1>`;
});
console.log(display);
});

Related

filter function shows an empty array

I want to create a search filter. The way it works is a user inputs a text in the search bar, the input is stored using vuex and the result is shown in a different page. Here's an array of objects in a js file
export const productData = [
{
id: 1,
name: "table",
materials: "wood"
},
{
id: 2,
name: "table2",
materials: "metal"
},
{
id: 3,
name: "chair",
materials: "plastic"
}
]
I want to filter using the user's input. Here's my function
import { productData } from '#/data/productData'
export default {
data() {
return {
products: productData
}
},
computed: {
userInput() {
return this.$store.state.userInput
},
filterProducts: function() {
return this.products.filter(q => q.name.match(this.userInput))
}
}
}
When I console the userInput, it works fine! So the problem is in the filterProducts function. It shows an empty array if I console it. What am I doing wrong? Thank you.
edit: the reason I make a new variable called products is because the actual js file is more complex so I had to flatten the array. But the flatten process works fine so I thought I would just simplify the question.
The match function accepts a regex, not String. Give indexOf a try:
filterProducts: function() {
return this.products.filter(q => q.name.indexOf(this.userInput) >= 0)
}

Make a new JS Object using an old one, see description for example

This one is pretty straight forward, I think I just don't know what tool to use. I've got an object which looks like this:
{
email: "email#aol.com", phone: "222-333-4444"
}
i am looking to convert it to the following array with nested objects
[
{
name: "email", value: "email#aol.com"
},
{
name: "phone", value: "222-333-4444"
},
]
im familiar with .map() and Oject.keys, just keep running into a wall on this one.
this is what i've been trying but im getting syntax errors
const data = Object.keys(data).map(key => {name: key, value: data[key]});
can anyone help? hopefully some quick points for someone. thanks!
To return object from arrow function, you must wrap it in () doc
To return an object literal expression requires parentheses around expression
const data = {
email: "email#aol.com", phone: "222-333-4444"
};
const result = Object.keys(data).map(key => ({name: key, value: data[key]}));

Vue computed property changes the data object

I have basically this structure for my data (this.terms):
{
name: 'First Category',
posts: [
{
name: 'Jim James',
tags: [
'nice', 'friendly'
]
},
{
name: 'Bob Ross',
tags: [
'nice', 'talkative'
]
}
]
},
{
name: 'Second Category',
posts: [
{
name: 'Snake Pliskin',
tags: [
'mean', 'hungry'
]
},
{
name: 'Hugo Weaving',
tags: [
'mean', 'angry'
]
}
]
}
I then output computed results so people can filter this.terms by tags.
computed: {
filteredTerms: function() {
let self = this;
let terms = this.terms; // copy original data to new var
if(this.search.tags) {
return terms.filter((term) => {
let updated_term = {}; // copy term to new empty object: This doesn't actually help or fix the problem, but I left it here to show what I've tried.
updated_term = term;
let updated_posts = term.posts.filter((post) => {
if (post.tags.includes(self.search.tags)) {
return post;
}
});
if (updated_posts.length) {
updated_term.posts = updated_posts; // now this.terms is changed even though I'm filtering a copy of it
return updated_term;
}
});
} else {
return this.terms; // should return the original, unmanipulated data
}
}
},
filteredTerms() returns categories with only the matching posts inside it. So a search for "angry" returns just "Second Category" with just "Hugo Weaving" listed.
The problem is, running the computed function changes Second Category in this.terms instead of just in the copy of it (terms) in that function. It no longer contains Snake Pliskin. I've narrowed it down to updated_term.posts = updated_posts. That line seems to also change this.terms. The only thing that I can do is reset the entire data object and start over. This is less than ideal, because it would be loading stuff all the time. I need this.terms to load initially, and remain untouched so I can revert to it after someone clears their search criterea.
I've tried using lodash versions of filter and includes (though I didn't really expect that to make a difference). I've tried using a more complicated way with for loops and .push() instead of filters.
What am I missing? Thanks for taking the time to look at this.
Try to clone the object not to reference it, you should do something like :
let terms = [];
Object.assign(terms,this.terms);
let terms = this.terms;
This does not copy an array, it just holds a reference to this.terms. The reason is because JS objects and arrays are reference types. This is a helpful video: https://www.youtube.com/watch?v=9ooYYRLdg_g
Anyways, copy the array using this.terms.slice(). If it's an object, you can use {...this.terms}.
I updated my compute function with this:
let terms = [];
for (let i = 0; i < this.terms.length; i++) {
const term = this.copyObj(this.terms[i]);
terms.push(term);
}
and made a method (this.copyObj()) so I can use it elsewhere. It looks like this:
copyObj: function (src) {
return Object.assign({}, src);
}

How to return new array with dynamically populated properties?

So my call returns something like:
data:
{
nameData: 'Test33333',
emailData: email#email.com,
urlLink: link.com
additionalDetails: [
{
field: 'email',
value: 'other#email.com'
},
{
field: 'name',
value: 'name1223'
}
]
}
Now, I want to make a function that would take the passed parameter (data) and make an array of objects, that should look like below. It should be done in more generic way.
Array output expectation:
fullData = [
{
name: 'data_name'
value: 'Test33333'
},
{
name: 'data_email',
value: 'email#email.com'
},
{
name: 'data_url',
value: 'Link.com'
},
extraData: [
//we never know which one will it return
]
];
It should be done in the function, with name, for example:
generateDataFromObj(data)
so
generateDataArrFromObj = (data) => {
//logic here that will map correctly the data
}
How can this be achieved? I am not really proficient with JavaScript, thanks.
Assuming that you keep your data property keys in camelCase this will work for any data you add, not just the data in the example. Here I've used planetLink. It reduces over the object keys using an initial empty array), extracts the new key name from the existing property key, and concatenates each new object to the returned array.
const data = { nameData: 'Test33333', emailData: 'email#email.com', planetLink: 'Mars' };
function generateDataArrFromObj(data) {
const regex = /([a-z]+)[A-Z]/;
// `reduce` over the object keys
return Object.keys(data).reduce((acc, c) => {
// match against the lowercase part of the key value
// and create the new key name `data_x`
const key = `data_${c.match(regex)[1]}`;
return acc.concat({ name: key, value: data[c] });
}, []);
}
console.log(generateDataArrFromObj(data));
Just run a map over the object keys, this will return an array populated by each item, then in the func map runs over each item, build an object like so:
Object.keys(myObj).map(key => {return {name: key, value: myObj[key]}})

Destructure array of objects, default value

I would like to set the default value of an object property if the value is undefined.
When destructing from the tags array, the name property, I would like to rename the property to colour, and set the default value if its undefined.
How can I do that?
I currently get name not defined with the code below:
const {
description,
categories,
id,
title,
>> tags: [{ name: colour= 'none' }], <<
organizer: [{ organizer: organiser }],
venue: { venue }
} = event;
This gives me colour is undefined
const {
description,
categories,
id,
title,
tags: [{name:colour = "none"}={name:"none"}]=[{name:"none"}],
organizer: [{ organizer: organiser }],
venue: { venue }
} = event;
Sample data:
const sample = {"tags":[{"name":"red","slug":"red","term_group":0,"term_taxonomy_id":125,
"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw","id":125,"urls"}]}
or empty const sample = {"tags":[]}
Does this help?
var {x,y,z,t:[{name:colour = "none"}]=[{name:"none"}]} = {x:3,y:2,z:1,t:[{name:"gray"}]};
console.log(colour);//"gray"
If t does not exist in the object:
var {x,y,z,t:[{name:colour = "none"}]=[{name:"none"}]} = {x:3,y:2,z:1};
console.log(colour);//"none"
PS: It seems to be in your object "t" might be defined as an empty array, in that case:
var {x,y,z,t:[{name:colour = "none"}={name:"none"}]=[{name:"none"}]} = {x:3,y:2,z:1,t:[]};
console.log(colour);//"none"
PS2: Here is proof of concept from the sample data you provided:
var {x,y,z,tags:[{name:colour = "none"}={name:"none"}]=[{name:"none"}]} = {x:3,y:2,z:1,"tags":[{"name":"red","slug":"red","term_group":0,"term_taxonomy_id":125,
"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw","id":125,"urls":"some"}]};
console.log(colour);//"red"
Although I should say the original example you post and the sample data you provide do not have identical structure. In your original post other properties like description etc are outside the tags key whereas in the sample you provide everything is inside the tags array.

Categories