This question already has answers here:
Get all unique values in a JavaScript array (remove duplicates)
(91 answers)
Closed 8 months ago.
I am fetching some data in form of strings , and I would like to avoid any duplication when I map this array .
This is how I am using this function in React :
<Flex >
{allPrismicCollection.nodes.map((collection)=>
(
<Navbar>
<NavTitle>{collection.data.collection.text}</NavTitle>
<NavbarFlex>
{collection.data.slides.map((coll)=>
<>
{coll.slide.document.data.blogs.map((s)=>
<>
{s.blog.document.data.tags.map((t)=>
(
<NavLink><Link to='#'>{t.tag}</Link></NavLink>
)
)}
</>
)}
</>
)}
</NavbarFlex>
</Navbar>
)
)}
</Flex>
This is the JSON format of the array , it contains multiple blog fields and each field has various tags fields .
"blogs": [
{
"blog": {
"document": {
"id": "4a007c39-2053-5c5e-8f38-56ba8c3aced5",
"data": {
"tags": [
{
"tag": "Entertainment"
},
{
"tag": "Happiness"
},
{
"tag": "Philosophy"
}
]
}
}
}
},
{
"blog": {
"document": {
"id": "9e78be5c-08e7-5684-adaa-b788cb4020b7",
"data": {
"tags": [
{
"tag": "Life"
},
{
"tag": "Vacation"
},
{
"tag": "Drama"
}
]
}
}
}
}
]
}
}
}
},
When consoling s.blog.document.data.tags I get multiple arrays , I need to wrap them in a single array based on the collection name !
the t.tag will return some duplicated values and I don't want it , how can I solve this please ?
You can use a package named lodash installable via npm or yarn. Then import the uniq function to use.
E.g.
import { uniq } from 'lodash'
Your code should then look like this
{uniq(s.blog.document.data.tags).map((t)=>
(
<NavLink><Link to='#'>{t.tag}</Link></NavLink>
)
)}
If t is an object, like in your case then you will need to use uniqBy function instead.
import { uniqBy } from "lodash"
Then your code should be
{uniqBy(s.blog.document.data.tags, 'tag').map((t)=>
(
<NavLink><Link to='#'>{t.tag}</Link></NavLink>
)
)}
Related
This question already has answers here:
How to print array of object in react
(2 answers)
Closed 7 months ago.
const api = axios.create({
baseURL: 'https://iotserver-arha83.herokuapp.com/api/customers/'
})
class App extends Component {
state = {
courses:[]
}
constructor(){
super();
api.get('/').then(res =>{
this.setState({courses: res.data})
})
}
render(){return (
<div className="App">
<header className="App-header">
<table>
<tr><td>pk</td>{this.state.courses.map(course=><td>{course.pk}</td>)}</tr>
<tr><td>title</td>{this.state.courses.map(course=><td>{course.title}</td>)}</tr>
<tr><td>gateway</td>{this.state.courses.map(course=><td>{course.gateway}</td>)}</tr>
</table>
</header>
</div>
);}
}
export default App;
[
{
"pk": 1,
"title": "first",
"gateways": [1]
}, {
"pk": 2,
"title": "second",
"gateways": [2]
}, {
"pk": 5,
"title": "test",
"gateways": []
}, {
"pk": 6,
"title": "test",
"gateways": []
}
]
this is my code and I want to print every item on my website
but I can't print gateways because it's an array
I tried to change the gateway into string so it might be printed but didn't work
any ideas...?
note: this code should print every thing on the upper list
You need to iterate over the array only once using the map() method and render a tr for each element.
<table>
<tr>
<th>pk</th>
<th>title</th>
<th>gateway</th>
</tr>
{courses.map((course) => (
<tr key={course.pk}>
<td>{course.pk}</td>
<td>{course.title}</td>
<td>{course.gateways.join(",")}</td>
</tr>
))}
</table>
Property gateways is also an array which you can map too, however since you only want to render values you can use join(",") method instead.
On a side note, it's better to start using functional components.
I've currently implemented a means of setting my Formik initial values from an API call which is all working fine but I'm currently facing an issue with re-populating my react-select field from my initial values.
At the moment, my initial values (snippet) from API fetch call looks like this:
const emptyGroup = {
groupName: "",
groupValues: []
}
const INITIAL_FORM_STATE = {
myName: '',
allGroups: [emptyGroup]
};
"allGroups": [
{
"groupName": "Group Astro",
"groupValues": [
{
"value": "My Group A",
"label": "My Group A"
},
{
"value": "My Group B",
"label": "My Group B"
}
]
}
]
Below is my react-select component:
<ReactSelect
options={ myGroupOptions }
isMulti={true}
name={`allGroups.${index}.groupValues`}
onChange={(option) => formikProps.setFieldValue({`allGroups.${index}.groupValues`}, option.value)}
onBlur={formikProps.handleBlur}
value={ ????? }
/>
What I am unsure is, how do I feed the values from the groupValues array above back into value={ ?????? } so that when this <ReactSelect /> component is rendered, it displays the values: My Group A My Group B within it?
Just in case someone else comes across this issue/query, I managed to solve the issue as follows for value together with formik values:
<ReactSelect
options={ myGroupOptions }
isMulti={true}
name={`allGroups.${index}.groupValues`}
onChange={(option) => formikProps.setFieldValue({`allGroups.${index}.groupValues`}, option.value)}
onBlur={formikProps.handleBlur}
value={values.allGroups[index].groupValues}
/>
I have facing an issue in React js, I want to render all data from rest API and show with a numeric index.
Rest API:
[
{
"id": "1",
"start_date": "2020-05-08 09:45:00",
"end_date": "2020-05-08 10:00:00",
"full_name": "mirza",
"cust_full_name": "furqan",
},
{
"id": "2",
"start_date": "2020-05-08 02:45:00",
"end_date": "2020-05-08 03:00:00",
"full_name": "mirza",
"cust_full_name": "ahmed",
},
{
"id": "3",
"start_date": "2020-05-08 06:45:00",
"end_date": "2020-05-08 07:00:00",
"full_name": "mirza",
"cust_full_name": "ali",
}
]
my code:
render()
{
let FullNameSlot1 = null //FullNameSlot
let SecondFullNameSlot1 = null
let BaberNameSlot1 = null //BaberNameSlot
let SecondBaberNameSlot1 = null
if (this.state.appointmentdata && this.state.appointmentdata.length
this.state.appointmentdata[0].start_date.toString() > this.state.newprevious
)
{
FullNameSlot1 = (
<p key={0}>{this.state.appointmentdata[0].cust_full_name}</p>
)
BaberNameSlot1 = (
<p key={0}>{this.state.appointmentdata[0].full_name}</p>
)
}
i want to render data with array {index}
if (this.state.appointmentdata && this.state.appointmentdata.length
this.state.appointmentdata[1].start_date.toString() > this.state.newprevious
)
{
SecondFullNameSlot1 = (
<p key={1}>{this.state.appointmentdata[1].cust_full_name}</p>
)
SecondBaberNameSlot1 = (
<p key={1}>{this.state.appointmentdata[1].full_name}</p>
)
}
I want to render all data from rest API and show with a numeric index. Make my code it simple.
<p key={index}>{this.state.appointmentdata[index][0].cust_full_name}</p>
<p key={index}>{this.state.appointmentdata[index][1].cust_full_name}</p>
Demo:
https://codesandbox.io/s/agitated-elion-quqp1
What should i do? Any one help me?
You can use conditional rendering and your final condition is a ternary to either map the array of data to JSX or return null. The array::map first argument is the current element being iterated, and the second argument is the current index. When returning JSX like this though you need to return a single node. Here I've used a react Fragment and attached the key there. I also destructured the element properties you wanted to display.
Conditional Rendering
Lists and Keys
{
(this.state.appointmentdata &&
this.state.appointmentdata.length &&
this.state.appointmentdata[1].start_date.toString() > this.state.newprevious)
? this.state.appointmentdata.map(({ cust_full_name, full_name }, index) => (
<Fragment key={index}>
<p>{cust_full_name}</p>
<p>{full_name}</p>
</Fragment>
) : null
}
#adnan khan Welcome to Stackoverflow! to render an array of elements you can make use of Array.map function https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
In your example it might look like this
if(this.state.appointmentdata && this.state.appointmentdata.length){
this.state.appointmentdata.map((data ,index) => <p key={index}>{data.cust_full_name}</p> )
}
If you want to render elements dynamically then conditional rendering is an option
You can use map() on appointmentdata and create the same number of elements as objects in the result of API
Sample:
render() {
return (
<React.Fragment>
{
this.state.appointmentdata.length
?
this.state.appointmentdata.map(ele => {
return (
<React.Fragment>
<p key={`cf_${ele.id}`}>{ele.cust_full_name}</p>
<p key={`f_${ele.id}`}>{ele.full_name}</p><hr/>
</React.Fragment>
)
})
: "__"
}
</React.Fragment>
);
}
I have integrated spreadJS with react framework. In spreadjs they only use the header name specified in JSON and accordingly the data get displayed in the spreadsheet.
Can we have dynamic headers and their respective value using JSON?
import { SpreadSheets, Worksheet, Column } from '#grapecity/spread-sheets-react';
this.data = [
{
"id": 1934,
"date": "2018-11-01",
"value": 10.0
},
{
"id": 1935,
"date": "2018-12-01",
"value": 10.0
},
{
"id": 1935,
"date": "2018-12-01",
"value": 10.0
}
]
class SpreadJsSample extends React.Component {
render() {
return (
<div>
<SpreadSheets>
<Worksheet data={this.data}>
{this.data.map(index => {
<Column width={150} data={index.date} />;
})}
</Worksheet>
</SpreadSheets>
</div>
);
}
}
I am getting following errors
The above error occurred in the Worksheet component:
Uncaught Cannot read property 'type' of null
Any help will be appreciated. Thanks!
The function you're passing to .map() isn't returning anything, so your array of columns is currently [undefined, undefined, undefined].
You just need to return the <Column>:
{this.data.map(index => {
return <Column width={150} data={index.date} />;
})}
or
{this.data.map(index => <Column width={150} data={index.date} /> )}
I am trying to display a JSON object which is an array in React. I am able to write the React code for doing that. However, I am not able to see the output in my browser.
Here is my code:
import React, {Component} from 'react';
import data from '../articles';
export default class fetchData extends Component {
showData = (inputValue) => {
inputValue.forEach((temp) => {
return (
<h1> temp.article_id </h1>
);
});
}
render () {
return (
<h1> {this.showData(data)} </h1>
);
}
}
JSON object: (located in ../articles)
[
{
"article_id": "101",
"org_id": "10001",
"reported_by": "Srilakshmi",
"reported_on": "11-16-2016",
"author": "Sree",
"language": "English",
"src_url": "",
"key_words": "CS, Programming",
"status": "Draft",
"channel_ids": "IOE1",
"title": "CS 101 Lession",
"description": "CS 101 First Lession",
"file_on_disk": "",
"publish_on": "",
"Published_on": "",
"contentArray": ""
},
{
"article_id": "102",
"org_id": "10001",
"reported_by": "Srini",
"reported_on": "11-16-2016",
"author": "Srini",
"language": "English",
"src_url": "",
"key_words": "CS, DB",
"status": "Draft",
"channel_ids": "IOE2",
"title": "CS DB 101 Lession",
"description": "CS DB 101 First Lession",
"file_on_disk": "",
"publish_on": "",
"Published_on": "",
"contentArray": ""
}
]
Any help with getting the data to display would be highly appreciated.
3 mistakes here...
First:
<h1> temp.article_id </h1> won't print article ID. Use curly braces to print actual value
<h1>{ temp.article_id }</h1>
Second:
forEach array method just loops array, it does not create new one from values returned in callback. Use map method instead.
inputValue.map((temp) => {
return (
<h1> temp.article_id </h1>
);
});
Third:
you are not returning from showData method at all.
Edit your code to return newly created array of components (that array created using map method)
showData = (inputValue) => {
return inputValue.map((temp) => {
return (
<h1>{ temp.article_id }</h1>
);
});
}
Bonus:
make it short using arrow functions
showData = (inputValue) =>
inputValue.map(temp => <h1>{ temp.article_id }</h1>)