How to display data from map method only 5 item [closed] - javascript

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I have a external Json file that displays data within the site. And I need to limit the display to only 5.
const displayCharacters = (characters) => {
characters.sort((a, b) => {
return a.rate - b.rate;
});
characters.sort((a, b) => b.rate - a.rate);
characters.forEach(() => {
const htmlString = characters
.map((character) => {
return `
<div class="col-6 my-2" onClick="addToCart(${character.id} )"></div>
<div class="menu card my-3" style="width: 120px">
<div class="card-body">
<h5 class="menu-name">${character.nama}</h5>
<p> ${character.harga}</p>
</div>
</div>
</div>
`;
})
.join('') ;
charactersList.innerHTML = htmlString;
});
};
loadCharacters();
help me guys

You can use the JS slice method to slice the array before using the map method.
const displayCharacters = (characters) => {
characters.sort((a, b) => {
return a.rate - b.rate;
});
characters.sort((a, b) => b.rate - a.rate);
characters.forEach(() => {
const htmlString = characters
.slice(0, 5)
.map((character) => {
return `
<div class="col-6 my-2" onClick="addToCart(${character.id} )"></div>
<div class="menu card my-3" style="width: 120px">
<div class="card-body">
<h5 class="menu-name">${character.nama}</h5>
<p> ${character.harga}</p>
</div>
</div>
</div>
`;
})
.join('') ;
charactersList.innerHTML = htmlString;
});
};
loadCharacters();

console.dir(object,{depth:5})
At least in node.js

You can use index in foreach and check if index is less then or equal to 5
const displayCharacters = (characters) => {
characters.sort((a, b) => {
return a.rate - b.rate;
});
characters.sort((a, b) => b.rate - a.rate);
characters.forEach(funtion(data,index) { //Here you will take now index so on index based you can check data limit
const htmlString = characters
.map((character) => {
if(index=<5){ //it will run untill index is less then and equal to 5
return
<div class="col-6 my-2" onClick="addToCart(${data.id} )"></div>
<div class="menu card my-3" style="width: 120px">
<div class="card-body">
<h5 class="menu-name">${data.nama}</h5>
<p> ${data.harga}</p>
</div>
</div>
</div>
`;
}
})
.join('') ;
charactersList.innerHTML = htmlString;
});
};
loadCharacters();

Related

How to edit a value in localStorage with TypeScript [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 10 months ago.
Improve this question
I am working on a simple "Green Light, Red light" game using Angular, and I am storing players with their score and maxScore using localStorage.
I can already read each property from the array stored in the localStorage, but now I am stuck on modifying those values once I click a button.
This is the test array I am currently working with:
[{"name":"test1","score":3,"maxScore":8},{"name":"test2","score":10,"maxScore":22}]
This array is stored with a single key named "players", so it is an array of players.
My component looks like this:
game.component.ts
export class GameComponentComponent implements OnInit {
highScoreLS: number = this.getHighScoreData();
scoreLS: number = this.getScoreData();
highScore: number = 0;
score: number = 0;
state: string = 'RUN';
faArrowRightFromBracket = faArrowRightFromBracket;
faShoePrints = faShoePrints;
constructor() {}
ngOnInit(): void {}
addPoint() {
this.score++;
if (this.score > this.highScore) {
this.highScore = this.score;
}
this.changeHighScore();
this.changeScore();
}
removePoint() {
this.score--;
if (this.score < 0) {
this.score = 0;
}
this.changeHighScore();
this.changeScore();
}
changeState() {
if (this.state === 'RUN') {
this.state = 'PAUSE';
} else {
this.state = 'RUN';
}
}
getScoreData() {
let localStorageItem = JSON.parse(localStorage.getItem('players') || '[]');
let item = localStorageItem.find(
(item: { name: string }) => item.name === 'test1'
);
let sc = item.score;
return sc;
}
getHighScoreData() {
let localStorageItem = JSON.parse(localStorage.getItem('players') || '[]');
let item = localStorageItem.find(
(item: { name: string }) => item.name === 'test1'
);
let hs = item.maxScore;
return hs;
}
changeHighScore() {
let localStorageItem = JSON.parse(localStorage.getItem('players') || '[]');
let item = localStorageItem.find(
(item: { name: string }) => item.name === 'test1'
);
item.maxScore = this.highScore;
localStorage.setItem('players', JSON.stringify(item));
}
changeScore() {
let localStorageItem = JSON.parse(localStorage.getItem('players') || '[]');
let item = localStorageItem.find(
(item: { name: string }) => item.name === 'test1'
);
item.score = this.score;
localStorage.setItem('players', JSON.stringify(item));
}
}
And the html looks like this:
game.component.html
<div class="navbar navbar-dark bg-dark">
<div class="container">
<h2>Hi! 👋</h2>
<a class="navbar-brand" routerLink=""
><fa-icon [icon]="faArrowRightFromBracket"></fa-icon
></a>
</div>
</div>
<div class="container flex vh-100">
<div class="row m-3">
<h3>HIGH SCORE: {{ highScoreLS }}</h3>
</div>
<div class="row m-3">
<div class="card p-3">
<h3>{{ state }}</h3>
</div>
</div>
<div class="row m-3">
<h3>SCORE: {{ scoreLS }}</h3>
</div>
<div class="row m-3">
<div class="col">
<button class="btn btn-outline-success" (click)="addPoint()">
<fa-icon [icon]="faShoePrints"></fa-icon>
Left
</button>
<button class="btn btn-outline-success" (click)="removePoint()">
Right
<fa-icon [icon]="faShoePrints"></fa-icon>
</button>
</div>
</div>
</div>
The problem is, when I click the button to add or remove a point, it deletes the whole array of players, and creates a new one like the following:
{"name":"test1","score":0,"maxScore":1}
I have been working for a couple of days with localStorage so I do not know exactly what I am missing or what I am doing wrong.
My idea is to edit those values, score and maxScore, but I can't figure it out how.
EDIT
The first time I click on add a point, it edits only the maxScore, but once. The next time I click, it gives me this error:
ERROR TypeError: localStorageItem.find is not a function
at GameComponentComponent.changeScore (game-component.component.ts:83:33)
at GameComponentComponent.addPoint (game-component.component.ts:34:10)
You're calling localStorage.setItem with just the single item and not the whole array so every subsequent "finds" you're trying will fail.
Try this instead:
localStorage.setItem('players', JSON.stringify(localStorageItem));
Though I have to say, there's loads of duplicate code in just that one component. You should read some articles on data structures and state management.

How to display specified number of data through link parameter?

I want to display from json server for example 5 of 100 objects. Is there any parameter like this one which sort?
const url = "http://localhost:8000/players?_sort=points&_order=desc";
const url = "http://localhost:8000/players?_sort=points&_order=desc";
let template = "";
fetch(url)
.then((res) => res.json())
.then((data) => {
data.forEach((player, idx) => {
template += `
<div class='modal-leaderboard__player-name'>
<h2>${idx + 1}. </h2>
<h2 data-player-rank>${player.name} </h2>
<h2 style='margin-left: auto'> <span data-points-rank>${player.points}</span> points</h2>
</div>
`;
});
this.rank.innerHTML += template;
});
if you mean fo example the first 5 items, can add a condition on var idx :
...
if(parseInt(idx)<6){
template+=...
....
this.rank.innerHTML += template;
}
...

Json file struggling with the length

So, i got everything almost working as i want it, just a mistake that im struggling. Everytime i search for an item, when the result for that item shows the length is repeated.
When i search for ox there are 2 results and that is correct, but the length (2) shows in both of them, i only display one
[Code]
const resultHtml = (itemsMatch) => {
if (itemsMatch.length > 0) {
const html = itemsMatch
.map(
(item) => `
<span>${itemsMatch.length}</span>
<div class="card">
<div class="items-img">
</div>
<div class="items-info">
<h4>${item.title}</h4>
<small>${item.path}</small>
</div>
</div>
`
)
.join('');
//console.log(html);
itemList.innerHTML = html;
}
};
////
Question 2
I got one more question, i was trying to get the image from the Json and what i got was the path haha
why the apth and not the img
const resultHtml = (itemsMatch) => {
if (itemsMatch.length > 0) {
const html =
`<span class="items-results">${itemsMatch.length} Resultados</span>` +
itemsMatch
.map(
(item) => `
<div class="card">
<div class="items-img">
${item.image}
</div>
<div class="items-info">
<h4>${item.title}</h4>
<small>${item.path}</small>
</div>
</div>
`
)
.join('');
console.log(html);
itemList.innerHTML = html;
}
};
If you move <span>${itemsMatch.length}</span> out of your map callback, it will not repeat for each item. Read more about map() here.
Replace:
const html = itemsMatch
.map(
(item) => `
<span>${itemsMatch.length}</span>
... more HTML here
`
)
.join('');
With this:
const html = `<span>${itemsMatch.length}</span>` + (
itemsMatch
.map(
(item) => `
<div class="card">
<div class="items-img">
</div>
<div class="items-info">
<h4>${item.title}</h4>
<small>${item.path}</small>
</div>
</div>
`
)
.join('')
);
Regarding your image issue:
You are just outputting the path and that's why it's printing out just the path. If you are trying to display an image then put the path as source of <img> tag.
So, instead of just:
${item.image}
Use:
<img src="${item.image}">

Map html element to json object [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have an html element like this,
<div class='myparent'>
<div>
<div class="pdp-product-price">
<span> 650 rupees</span>
<div class="origin-block">
<span> 1,500 rupees</span>
<span>-57%</span>
</div>
</div>
</div>
</div>
I need to create a json of this 'myparent' div.
{
"div": {
"div": {
"div": {
"span": {},
"div": {
"span": {},
"span": {}
}
}
}
}
}
Is there a way to do this in javascript?
You can use children property of HTMLElement
Then iterate over parent recursively and get subtree.
But be aware that you cannot assign two values with the same key. Therefore, you can use an index when assigning subtree like
"div": {
"span_1": {},
"span_2": {},
}
Hope the below snippet will give you a clue.
const parent = document.getElementById('parent')
const tree = {};
const getTree = (elem) => {
const subtree = {};
for(let child of elem.children){
subtree[child.tagName.toLowerCase()] = getTree(child)
}
return subtree;
}
tree[parent.tagName.toLowerCase()] = getTree(parent);
console.log(tree);
<div id="parent" class='myparent'>
<div>
<div class="pdp-product-price">
<span> 650 rupees</span>
<div class="origin-block">
<span> 1,500 rupees</span>
<span>-57%</span>
</div>
</div>
</div>
</div>
Recursive function that builds the json. To ensure no issues with the keys (that have a possibility to be duplicates) the following was added :n where n is the index of the element.
function htmlToObject(targetElement) {
return Array
.from(targetElement.children)
.reduce((acc, cur, i) => {
acc[`${cur.tagName}:${i}`.toLowerCase()] = htmlToObject(cur);
return acc;
}, {});
}
const startElement = document.getElementsByClassName("myparent")[0];
const res = {
[startElement.tagName.toLowerCase()]: htmlToObject(startElement)
};
console.log(res);
<div class='myparent'>
<div>
<div class="pdp-product-price">
<span> 650 rupees</span>
<div class="origin-block">
<span> 1,500 rupees</span>
<span>-57%</span>
</div>
</div>
</div>
</div>

React JS for loop inside rendering

I'm new to React JS and I'm not sure how to do a for loop to render something a variable number of times. This is my code:
<div className="product-selector__products">
{ this.props.products.sort(function(a,b) { return a.ranking - b.ranking }).map((p) => {
const className = "product" + ((this.props.selectedProductIds.indexOf(p.id) !== -1) ? " product--selected" : "");
const descriptionHtml = { __html: p.description };
const nameHtml = { __html: p.name };
return (
<div className={className} key={ p.id } onClick={this.onProductClick.bind(this, p.id)}>
<div className="product__image">
<img src={`/~/media/Bayer CropScience/Country-United-States-Internet/Comparison Tool/img/logos/${p.id}_sm.png`} alt={p.name} />
</div>
<div className="product__info">
<div className="product__name" dangerouslySetInnerHTML={nameHtml}></div>
<div className="product__description" dangerouslySetInnerHTML={descriptionHtml}></div>
</div>
<div className="product__message" ref={ p.id }>
<div className="product__message-tooltip">Please remove a product<br/>before adding another</div>
<div className="product__message-triangle-down"></div>
</div>
</div>
);
}) }
/* Here I want to render <div className="product product--empty"> </div> a variable number of times*/
</div>
It generates a grid of product items, with 4 items per row.
I need to add empty divs onto the end of the last row so that each row has the same number of divs in it.
So if this.props.products.length == 7 I need 1 empty div, and if I have 5 products I need 3 empty divs, etc.
The script i want is this:
let remainder = 4 - (this.props.products.length % 4);
for (let i = 0; i < remainder; i++){
return ( <div className="product product--empty"> </div> )
}
I'm not sure how to properly put this into the code-block though.
I've just modified a little Your code.
renderRemainders() {
let products = []
let remainder = 4 - (this.props.products.length % 4)
for (let i = 0; i < remainder; i++){
products.push( <div className="product product--empty"> </div> )
}
return products
}
And just put
{ this.renderRemainders() }
somewhere in Your 'render' function.
Also, could You say something about why you need to render these empty rows?

Categories