I have some data from dummy back-end for example:
[
{
"title": "title title 0",
"date": "22/09/2015",
"author": "author00",
"langs": [
"react",
"javascript"
]
},
{
"title": "title 1",
"date": "09/11/2012",
"author": "author188",
"langs": [
"angular",
"vue"
]
}],
I try to stylize "langs" array by it's first element, example:
const posts = this.state.posts.map(post => {
if (post.tags[0].startsWith("react")){
post.style.backgroundColor = "red";
}
}
I think 'if' statement is correct but I don't know what to try in codeblock.
when I try to log in console somewhat it is ok.
but many things on this case depends on what is the first [0] element in the array...
for example, if first element contains 'angular' in cideblock many style options must be rearanged on red color, and when it contains 'react' the dominant style color in every case must be a blue color.
can you advice me generally what is the best solution for changing styles of lots of things with if/else statement?
Make a color map that defines colors for code tags like this:
const colorMap = { 'react': 'red', 'angular': 'blue' };
then use it like this:
const posts = this.state.posts.map(post => {
const tag = post.tags[0];
const color = colorMap[tag];
post.style.backgroundColor = color;
});
Related
I want to update a single Object in my localStorage. I made a detail page, where I can submit new values (progress and value)
When I want to update the value, it changes the value in both objects. How can I change just one object.
Here is my deployment link.(its work in progress)
https://mastery-app.herokuapp.com/
This is my localStorage array:
skills[
{
"title": "Sewing",
"imageSrc": "images.unsplash.com",
"description": "Make your own clothes",
"category": "crafting",
"progress": 500,
"isDone": false,
"rank": 0,
"value": 0
},
{
"title": "Crocheting",
"imageSrc": "images.unsplash.com",
"description": "Interlock loops of yarn",
"category": "crafting",
"progress": 500,
"isDone": false,
"rank": 0,
"value": 0
}
]
This is how I update the localStorage:
const update = skills.map((skills) => {
skills.title === skills.title;
const updateProgress = skills.progress - value;
const rankNumber = parseInt(ranking);
const updateRank = skills.rank + rankNumber;
console.log(updateRank);
const updateValue = skills.value + value;
return {
title: skills.title,
rank: updateRank,
description: skills.description,
progress: updateProgress.toFixed(1),
imageSrc: skills.imageSrc,
category: skills.category,
isDone: false,
value: updateValue,
};
});
localStorage.setItem('skills', JSON.stringify(update));
You may consider using the find method to find the object you want to update. map is not the right function to be used for your use case.
Also skills.title === skills.title; has no effect at all (Maybe you wanted to use an if statement to do some kind of filtering by using title but that always would return true). Please remove that.
Now, I don't exactly know which field are you going to use to search for the object you want to update, but it has to be unique. If none of the fields in the objects are unique you should consider adding an unique id field in the skills objects. But if title is unique you can use the title to search. Then you can do something like the pseudo code below:
const toUpdate = skills.find(skill => skill.title === your_title_here)
toUpdate.field_to_update_1 = some_value_1
toUpdate.field_to_update_2 = some_value_2
localStorage.setItem('skills', JSON.stringify(skills))
Please also check the MDN docs to see how map, find and other array methods work and some of their use cases.
I have implemented my app in English, and I am looking for a way to cover 3 other langs.
I have thought to create a module langs.js
and then, create a map like this one:
const texts = {
"spanish": {
"home": {
"header": "Hello",
"footer": "World"
},
...
},
...
}
But... is that the way? Any ideas? This is my fist time doing something like this.
I'm currently building a website on Wix, and have come across a problem I can't think myself out of. Neither Wix support or the Wix Velo Forum have been able to help me out.
I have a repeater that is connected to the Stores/Products collection, and in the Stores/Products collection there's a collection field that contains additional info sections on the product. I have three info section; Tempo, Genre and Tags. Each contains a description.
It looks like this:
[
{
"title": "Tempo",
"description": "<p>142 BPM</p>\n"
},
{
"title": "Genre",
"description": "<p>Jazz</p>\n"
},
{
"title": "Tags",
"description": "<p>Frank Ocean, Travis Scott</p>\n"
}
]
I have figured out how to pull the individual objects with this code:
export function audioRepeater_itemReady($item, itemData, index) {
let product = $item('#dataset3').getCurrentItem(itemData._id)
let ArrayAdditionalInfo = []
ArrayAdditionalInfo = product.additionalInfoSections
ArrayAdditionalInfo.forEach((element) => {
console.log(element.title)
console.log(element.description)
})
But I want it to be able to figure out if eg. the Title === "Genre", then it will show the description from that array, like this:
{
// if equal to this:
"title": "Genre",
// show me this
"description": "<p>Jazz</p>\n"
},
The whole plan with this is to show the description output in a text element that I can implement in the repeater.
I have tried with if statements, but I just can't put it together myself. If this is confusing I'll gladly elaborate.
Thank you in advance.
I'm not a 100% sure if I understood the question correctly, but if you want to show all titles, and, conditionally the description if the title is Genre, you could just use a Ternary:
let data = [{
"title": "Tempo",
"description": "142 BPM\n"
},{
"title": "Genre",
"description": "Jazz\n"
},{
"title": "Tags",
"description": "Frank Ocean, Travis Scott\n"
}];
data.forEach(e => $("#products").append(
`<p>Title: ${e.title}${
e.title === "Genre"
? "<br>description: " + e.description
: ""
}</p>`
));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="products">
</div>
I think your issue related to handler. You use repeaters onItemReady handler, which is not the best option for your case. It calls for each row in repeater. Instead of this I recommend to use dataset's onReady
$w("#dataset3").onReady( () => {
console.log("The dataset is ready");
$w("#audioRepeater").getItems(0, 20).then( (result) => {
let items = result.items;
items.forEach((element) => {
if (element.title === 'Genre') {
doWhatDoYouWant(element)
}
})
} ).catch( (err) => {
let errMsg = err.message;
let errCode = err.code;
} );
} );
Please take into consideration that this block should be inserted into $w.onReady
I'm currently working with react to read and display the elements given in a json file.
As far as this, everything works fine. Now I want to display a text in a label of a checkbox which should also be able to contain links without turning the whole label in a link.
To do this I made this json structure:
"labels": [
"Text without a link",
{
"url": "google.de",
"label": "Link text"
}
]
And to display these side by side I'm mapping over the json Array "labels"
labels: Array<Object>;
labels.map(el => {
if (isString(el))
return el;
else
return <Link href={el['url']} color="inherit">{el['label']}</Link>
})
But I can't access el['url'] or el['label'].
It throws:
"Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'Object'."
Probably I'm just overseeing something unbelievable simple. Help would be nice!
Cheers,
m3_
Try this:
return <Link href={el.url} color="inherit">{el.label}</Link>
Try this
var data = {
"labels": [
"Text without a link", {
"url": "google.de",
"label": "Link text"
}
]
}
const links = data.labels.map(item => {
if(isString(item)) {
return item
}
const { url, label } = item
return <Link href={ url } color="inherit">{ label }</Link>
})
"labels": [
"Text without a link",
{
"url": "google.de",
"label": "Link text"
}
]
here, labels is an array which has values of type string and object. For strings it wont have url and label properties. So while parsing every value using map function, you have to check the type of value is object or not. If it is an object then only check url and label for it.
This React code is filtering variables according to the "tag" which it contains (as seen in the list array).
However, I cannot toggle the filter variables (tags) on/off.
I want to be able to turn certain filters on/off, and have just those filters apply.
How is this achieved?
My entire code is in this codepen (
http://codepen.io/yarnball/pen/GqbyWr?editors=1010)
I believe I have to some how add it to the array on line 79 (below), but I have not had success with this
Line 79:
selectTag: function (tag) {
this.setState({
displayedCategories: this.state.displayedCategories.concat([tag]),
$push : [newObject]
});
},
My data looks like this:
"title": "Into the Wild",
"tag": [
{
"name": "Movie",
"taglevel": 1,
"id": 1
},
{
"name": "Adventure",
"taglevel": 2,
"id": 30
},
{
"name": "Book",
"taglevel": 1,
"id": 2
}
],
"info": []
}
In order to toggle the filters, you will need to check for the existence of the tag in the existing displayedCategories, look through the array for the tag, and then either remove it or add it in.
It is normally my preference to try to be functional so that assignment cannot cause confusion, so I will use a mostly functional style.
First to check for the presence of the tag we can use a filter operation.
var filteredCategories = this.state.displayedCategories
.filter(function (existingTag) {
return existingTag.taglevel !== tag.taglevel ||
existingTag.id !== tag.id;
});
So we now have a list of tags that are filtered to only include those that don't match the passed tag. We can check if the filtered list is the same size as the old list to see if we removed one. Alternatively, we could have filtered the other way around to see if we needed to remove one using some.
if (filteredCategories.length === this.state.displayedCategories.length){
// tag wasn't present, add it
} else {
// tag was present, use filtered list.
}
As I said above, I prefer functional, so we can do it slightly differently:
var newCategories = filteredCategories.length === this.state.displayedCategories.length ?
filteredCategories.concat([tag]) :
filteredCategories;
and then we need to set state:
this.setState({
displayedCategories: newCategories,
});
To combine those together:
var filteredCategories = this.state.displayedCategories
.filter(function (existingTag) {
return existingTag.taglevel !== tag.taglevel ||
existingTag.id !== tag.id;
});
var newCategories = filteredCategories.length === this.state.displayedCategories.length ?
filteredCategories.concat([tag]) :
filteredCategories;
this.setState({
displayedCategories: newCategories,
});