How to seperate item in array using react - javascript

user.js
import React, { useState, useEffect } from 'react';
import Axios from 'axios';
const RecommendationDetail = () => {
const [image, setImage] = useState([]);
useEffect(() => {
loadRekko();
}, []);
const loadRekko = async () => {
const res = await Axios.get(`http://localhost:3001/dashboard-rekko/${id}`,{
headers:headers
});
console.log(res.data.response);
var array = [];
let a = (res.data.response.rekkoRecords.product_img)
array.push(a)
setImage(array) ====>>> How can i make array like i want
console.log(image)
setRecommendation(res.data.response.rekkoRecords)
}
return (
{image.map((it) => {
return (
<div key={it}>
<img src= {'http://localhost:3001/'+it} />
</div>
)
})}
)
}
Everything is working but I want to show multiple images. I am getting a response in "uploads\classpamplate.png,uploads\classpamplate1.jpg" this format and after pushing it in the array it becomes ["uploads\classpamplate.png,uploads\classpamplate1.jpg"] but what I want is ["uploads\classpamplate.png","uploads\classpamplate1.jpg"] both are separated so that I can show it using .map() function. Any help will be appreciated

You can use .split() to separate that string by comma ,:
The split() method divides a String into an ordered list of substrings, puts these substrings into an array, and returns the array.
let a = (res.data.response.rekkoRecords.product_img)
setImage(a.split(','))
See a live example below:
const data = `uploads\classpamplate.png,uploads\classpamplate1.jpg`
const result = data.split(',')
console.log(result)

Just split the string by ,. it will return a new array
let result = (res.data.response.rekkoRecords.product_img).split(',');
let array = [...result];

You can split them using , so that it'll be converted to an array
let a = (res.data.response.rekkoRecords.product_img).split(",");
array.push(...a)
or
Directly you can call setImage like below
setImage(res.data.response.rekkoRecords.product_img.split(","));
Check if the response is empty or not and then split
let a = (res.data.response.rekkoRecords.product_img);
a = a && a.split(",") || []
setImage([...a])

I am assuming
a = "uploads\classpamplate.png,uploads\classpamplate1.jpg"
expected result = ["uploads\classpamplate.png","uploads\classpamplate1.jpg"]
Don't push a in the array, try below
setImage(a.split(','))

Related

Add data into Array in local storage, React

I'm trying to store the page Id in an array stored in local storage every time a user load a page.
I have my array, it create one if needed but for some reasons it does not update the array in new page load and keeps the first page Id.
I want to add the page id in that array on every page load if the id is not already in that array.
I've tried a lot of things but it seems like I don't understand something, any help ? Thanks
Here is my code
const [isPostId, setItems] = useState([postId]);
useEffect(() => {
//const items = JSON.parse(localStorage.getItem('items'));
if (JSON.parse(localStorage.getItem('isPostId')) == null) {
localStorage.setItem('isPostId', JSON.stringify(isPostId));
}
if (!isPostId.includes(postId)) {
JSON.parse(localStorage.getItem('isPostId'))
localStorage.setItem('isPostId', JSON.stringify(isPostId));
} },[isPostId]);
EDIT: It works now, looks like I was confused about how localStorage works, now it's clear thanks for your help everyone
Both are working:
useEffect(() => {
const storageKey = "isPostId";
const json = localStorage.getItem("isPostId");
const previousPosts = json ? JSON.parse(json) : [];
const filtered = previousPosts.filter((it) => it !== postId);
const updatedPosts = [...filtered, postId];
const stringifyed = JSON.stringify(updatedPosts);
localStorage.setItem("isPostId", stringifyed);
console.log('heu',filtered)
}, [])
useEffect(() => {
// options a - full replace
localStorage.setItem('isPostId', JSON.stringify(isPostId));
// option b - only add unique, don't remove previous
var currentIds = JSON.parse(localStorage.getItem('isPostId')) || [];
isPostId.map((e) => {
if (!currentIds.includes(e) {
currentIds.push(e);
}
})
localStorage.setItem('isPostId', JSON.stringify(currentIds));
}, [isPostId])
Right now the code in the first if statement will put ONE id in local storage if there isn't one already, but not as an array. The code in the second if statement will also only set one id. You need to be setting an array value as shown below
If isPostId is declared as an array:
useEffect(() => {
// options a - full replace
localStorage.setItem('isPostId', JSON.stringify(isPostId));
// option b - only add unique, don't remove previous
var currentIds = JSON.parse(localStorage.getItem('isPostId')) || [];
isPostId.map((e) => {
if (!currentIds.includes(e) {
currentIds.push(e);
}
})
localStorage.setItem('isPostId', JSON.stringify(currentIds));
}, [isPostId])
If isPostId is declared as a string:
If you are certain there will not be single string values in localStorage and there will only be null values or arrays, you can do this as such:
useEffect(() => {
var currentIds = JSON.parse(localStorage.getItem('isPostId')) || [];
if (!currentIds.includes(isPostId) {
currentIds.push(isPostId);
}
localStorage.setItem('isPostId', JSON.stringify(currentIds));
}, [isPostId])
If there is a possibility that there could be individual string values, you will need an additional check for the code inside the useEffect
var currentIds = JSON.parse(localStorage.getItem('isPostId'));
if (!currentIds?.length) {
currentIds = [];
} else if (typeof currentIds !== 'object') {
// value in localStorage is a single string/number rather than an array
currentIds = [currentIds]
);
if (!currentIds.includes(isPostId) {
currentIds.push(isPostId);
}
localStorage.setItem('isPostId', JSON.stringify(currentIds));
Could simplify the second chunk further if desired
If I understood the question correctly, then you need something like this solution.
useEffect(() => {
const storageKey = "isPostId";
const json = localStorage.getItem("isPostId");
const previousPosts = json ? JSON.parse(json) : [];
const updatedPosts = [...previousPosts, ...isPostId];
const uniquePosts = Array.from(new Set(updatedPosts))
const stringifyed = JSON.stringify(uniquePosts);
localStorage.setItem("isPostId", stringifyed);
}, [])

Creating Array out of comma seperated list in React JS

I have an input for users to come and paste one id or multiple with each seperated by a comma then run a function on the individual Id's.
<Input type={'text'} placeholder="Id(s) (seperated by comma if more than 1)" value={ids} onChange={(event) => setIds(event.target.value)} />
Then I have the React useState constants for using the individial ids
const [ids, setIds] = useState(["ID#1", "ID#2"]).split("[\\s,]+")
const [id, setId] = useState(addresses[0]);
Here is where I set the function for picking each individual ID and running the function
const fetchNft = async (e) => {
for(let i = 0; i< ids.length; i++){
const _id = id[i]
const idInfo = await find(_id);
console.log(idInfo)
}
}
This doesn't make any sense:
useState(["ID#1", "ID#2"]).split("[\\s,]+")
useState returns an array containing the state value and the setter function for the state value. There's nothing to "split", and in this case neither of those values are strings.
You probably meant to put that split logic here:
setIds(event.target.value.split("[\\s,]+")
Since the input value is the string of comma-separated values that you want to split into an array.
This can't possibly work
const [ids, setIds] = useState(["ID#1", "ID#2"]).split("[\\s,]+")
You need to first call useState and then split on the first returned value. You can't split the return value of useState given that it is an array.

How to get all the 'items' of an API array from GitHub?

I am trying to get a list of repositories, that is my code does a search for repositories with a filter
The Javascript gets a result, with multiple items that contain the data for each repository that fit the filter using the URL: https://api.github.com/search/repositories?q=piccolowen+in:name.
I can do console.log(result.items[0].name) to get the first repository's name value, but I want get all of the repositories from the search printed to the console. I also want the code to be able to print all of the repositories and their values no matter how many repos fit the filter.
Here is the current code I want to add on to:
window.onload = func()
async function func() {
const url = 'https://api.github.com/search/repositories?q=piccolowen+in:name'
const response = await fetch(url);
const result = await response.json();
const apiresult = document.getElementById('thisisanid')
console.log(result)
}
Any ideas on how I could do this?
EDIT:
I found the answer to my problem using a while loop from this question: Get total number of items on Json object?
const resultLength = Object.keys(result.items).length
var arrnum = 0
while (arrnum < resultLength) {
//execute code
}
EDIT 2:
The code in my previous edit will crash a page. Still working on a solution for this huge bug.
Since results.items returns an array of objects, you can use Array.prototype.map to return all the item names, i.e.:
result.items.map(item => item.name)
If you want to simply filter out some properties, you can also do object destructuring. Let's say you want an array of items that only contain their name, id, and description, then you can do this:
result.items.map(({ name, id, description }) => ({ name, id, description }))
async function func() {
const url = 'https://api.github.com/search/repositories?q=piccolowen+in:name'
const response = await fetch(url);
const result = await response.json();
// Returns an array of item names
console.log(result.items.map(item => item.name));
// Returns an array of object with selected keys
console.log(result.items.map(({ name, id, description }) => ({ name, id, description })));
}
func();
The array has map function, which accepts a callback function. It iterate through all the elements and call the callback function and push data to the newly created array.
The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.
More:
Array.map
const array1 = [1, 4, 9, 16];
// pass a function to map
const map1 = array1.map(x => x * 2);
console.log(map1);
// expected output: Array [2, 8, 18, 32]
window.load = main();
const nameMapper = (item) => item.name;
const liMapper = (item) => `<li>${item.name}</li>`;
async function main() {
const url = "https://api.github.com/search/repositories?q=piccolowen+in:name";
const result = await fetch(url).then((x) => x.json());
const names = result.items.map(nameMapper);
const apiresult = document.getElementById("thisisanid");
apiresult.textContent = names;
const ul = document.getElementById("list");
ul.innerHTML = result.items.map(liMapper).join("");
}
#list li{
list-style: none;
padding: 5px 10px;
border: 1px solid black;
max-width: 400px;
}
<div id="thisisanid"></div>
<ul id="list">
</ul>
You can use like!
let list = document.getElementById('list');
let htmlTemplate = result.items.map(function(item) {
return item.name
}).join("")
list.insertAdjacentHTML('beforeend', htmlTemplate)
or you can use template literal
foe example
when you returning value in items.map()
return `${item.id}: ${item.name}`

Array order changed after multiple array.sort

I have a code to sort array
const timeSorted = wheater.list.sort((z,x)=>
{
return z.dt- x.dt
})
console.log(timeSorted)
Output that i get is sorted
but if i add another sort like this
const timeSorted = wheater.list.sort((z,x)=>
{
return z.dt- x.dt
})
const tempSorted = wheater.list.sort((a,b)=>
{
return a.main.temp - b.main.temp
})
console.log(timeSorted)
const timeSorted become tempSorted
How can i fix that?
The array is sorted in place.
In order to not have it changed, you need to create a copy of the previous array using oldArray.slice().
const tempSorted = wheater.list.slice().sort((a,b)=>
{
return a.main.temp - b.main.temp
})

Check string for array elements and systematically replace them with HTML tags - (JS, ReactJS)

I need to search a string, and if it has any values that match my array, I need to add <span></span> tags to them to add custom CSS. I am using reactJS.
How do I search the string for objects from my array?
Example:
let string = 'this is a message with many inputs, {{input1}}, {{input2}}, and again {{input1}}'
let array = [{parameter: '{{input1}}'},{parameter: '{{input2}}'},...]
findAllOccurrances = () => {???}
Then systematically replace them '{{inputX}}' with <span className='bizarre-highlight'>{{inputX}}</span>
My intent is to add custom CSS to any text in the div which matches my array, so if you got any ideas please shoot! Again, using reactJS if that helps.
I created a component that will replace the elements that need to be highlighted with a span you can test it here
The component is:
import React from 'react';
export default ({ terms, children }) => {
const result = []
const regex = terms.map(escapeRegExp).join('|');
const re = new RegExp(regex);
let text = (' ' + children).slice(1); // copy
let match = re.exec(text);
while (match != null) {
const str = match.toString();
result.push(text.slice(0, match.index));
result.push(<span className="highlighted">{str}</span>);
text = text.slice(match.index + str.length);
match = re.exec(text);
}
result.push(text);
return result;
}
function escapeRegExp (str) {
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&");
}
And you should use it like this:
import React from 'react';
import Highlighter from './Highlighter';
const terms = [ '{{input1}}', '{{input2}}' ]
const App = () => (
<div>
<Highlighter terms={terms}>
{'this is a message with many inputs, {{input1}}, {{input2}}, and again {{input1}}'}
</Highlighter>
</div>
);
Use String#replace with a RegExp to find all instances of '{{inputX}}', and wrap the matches with the span:
const string = 'this is a message with many inputs, {{input1}}, {{input2}}, and again {{input3}}'
const array = [{parameter: '{{input1}}'},{parameter: '{{input2}}'}]
const pattern = new RegExp(array.map(({ parameter }) => parameter).join('|'), 'g');
const result = string.replace(pattern, (match) =>
`<span className='bizarre-highlight'>${match}</span>`
)
console.log(result)
use Array#map to extract values for wrapping in <span> and then cycle on them for replacement:
let string = 'this is a message with many inputs, {{input1}}, {{input2}}, and again {{input1}}';
let array = [{parameter: '{{input1}}'},{parameter: '{{input2}}'}];
array.map(el => { return el.parameter }).forEach(str => {
string = string.split(str).join("<span className=\'bizarre-highlight\'>" + str + "</span>");
});
console.log(string);

Categories