I'm very new to React and Javascript. I am creating a simple search feature using React and Nodejs where you are able to search for tutors. I am trying to print the output of the search using react. My express server sends a response in the form of a string. It looks like the following:
'[{"tutorID":1,"email":"[email protected]","firstName":"John","lastName":"Doe","courseTeaching":"csc510","imageReference":" http://localhost:3001/john.png "}]'
I want to be able to display every key and its value in the form of a table. Can someone please help me achieve this?
The code for my search in react is given below:
import React, {useState} from 'react';
import "./SearchForm.css";
import SearchIcon from '@mui/icons-material/Search';
import DisplayResults from './DisplayResults.js';
class SearchForm extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedCategory: '',
textSearch: '',
searchResponse: []
};
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.value;
const name = target.name;
this.setState( {
...this.state,
[target.name]: value
});
}
handleSubmit(event) {
event.preventDefault();
let cat = this.state.selectedCategory;
let searchquery = this.state.textSearch;
fetch(`http://localhost:3000/onSubmit?param1=${cat}¶m2=${searchquery}`, {
method: "GET",
headers: {
'Content-type': 'application/json'
}
})
.then((result, err) => result.json())
.then(contents => {
this.setState({ searchResponse: contents}, function() {
console.log(this.state.searchResponse);
})
});
}
render() {
return (
<>
<p className="greeting">Hi, what would you like to search?</p>
<form onSubmit={this.handleSubmit}>
<div className="wrapper">
<select class="theme"
name="selectedCategory"
type="category"
value={this.state.selectedCategory}
onChange={this.handleInputChange}>
<option value="all">Search All</option>
<option value="tutors">Tutors</option>
<option value="Courses">Courses</option>
</select>
<input className="searchBar"
name="textSearch"
type="text"
placeholder="search"
value={this.state.textSearch}
onChange={this.handleInputChange}>
</input>
<div className="searchIcon">
<SearchIcon onClick={this.handleSubmit}/>
</div>
</div>
</form>
<DisplayResults searchResults={this.state.searchResponse}/>
</>
)
}
}
export default SearchForm;
The code for the DisplayResults is below:
import React from 'react';
class DisplayResults extends React.Component {
render() {
return (
<div>{this.props.searchResults}</div>
);
}
}
export default DisplayResults;
Any help would be much appreciated, thank you.
CodePudding user response:
What you could do if the response was JSON is to use the .map property.
In this example I omitted the ' ' (at the start and end) from your set of data, to make it valid json.
let object = [{
"tutorID": 1,
"email": "[email protected]",
"firstName": "John",
"lastName": "Doe",
"courseTeaching": "csc510",
"imageReference": " http://localhost:3001/john.png "
}]
So you could probably do something like this to access the values.
const listItems = object.map((object) => console.log(object.tutorID))
So with .map you can return a component with the data, you just mapped over.
So after that it's up to you what you want to do with the data. So you can create a table, or use one from Bootstrap or something similar and just map the values out.
<Table>
<p>{object.tutorID}</p>
<p>{object.email}</p>
<p>{object.firstName}</p>
<p>{object.lastName}</p>
...
</Table>
If I said anything wrong, or if I didn't quite give you the answer you wanted then let me know.
CodePudding user response:
- [Inside SearchForm] After receiving the response, let's turn your string data into something usable. Parse your string to an array of objects using
JSON.parse(YOUR_DATA)
. You can then set your searchResponse state to this array. - [Inside DisplayResults] You have an array of objects, so iterate over them using
YOUR_DATA.map()
. Your map function should return some JSX. In this case you are making a table. This is a function which creates the table. We useObject.values(YOUR_OBJECT)
to get all the values (e.g.John, Doe ...
) andObject.keys(YOUR_OBJECT)
to get the keys (e.g.firstName, lastName
). You can use something like this in yourrender()
function to create the table.
const createTable = () => {
const tableHeaders = ( // Get the table headers from the first person, OR enter them manually.
<tr>
{Object.keys(this.props.searchResults[0]).map(headerTitle => <th>{headerTitle}</th>)}
</tr>
);
// All the content rows of the table.
const tableRows = this.props.searchResults.map((tutor) => (
<tr> {/* this is one row of the table. It is filled with td's which each have a piece of information about the tutor. */}
{Object.values(tutor).map(value => ( // for each of the properties of the tutor, we create a table cell.
<td>{value}</td>
))}
</tr>
));
// The actual table, with table headers and table rows.
return (
<table>
{tableHeaders}
{tableRows}
</table>
);
}