Display the specfied list in frontend - reactjs

Goal:
Display the content of listGetAllIndustry in frontend.
Problem:
"Error: Objects are not valid as a React child (found: object with keys {listGetAllJobAdvertisement, listGetAllLocation, listGetAllIndustry}). If you meant to render a collection of children, use an array instead."
What part of the code am I missing in order to display the content of listGetAllLocation at frontend?
Info:
*I'm new in React JS
Thank you!
{"listGetAllJobAdvertisement":[],"listGetAllLocation":[{"locationId":1,"city":"LOS ANGELES","country":"USA"},{"locationId":2,"city":"LONDON","country":"ENGLAND"},{"locationId":3,"city":"BERLIN","country":"GERMANY"}],"listGetAllIndustry":[{"industryId":1,"name":"ENERGY"},{"industryId":2,"name":"MATERIALS"},{"industryId":3,"name":"INDUSTRIALS"},{"industryId":4,"name":"CONSUMER STAPLES"},{"industryId":5,"name":"HEALTH CARE"},{"industryId":6,"name":"FINANCIALS"},{"industryId":7,"name":"INFORMATION TECHNOLOGY"},{"industryId":8,"name":"COMMUNICATION SERVICES"},{"industryId":9,"name":"UTILITIES"},{"industryId":10,"name":"REAL ESTATE"}]}
import { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
import { VacantPositions } from '../../src/contexts/api';
class Open extends Component {
state = { aaa: [] };
componentDidMount() {
fetch(VacantPositions)
.then(results => results.json())
.then(data => this.setState({ aaa: data } ))
.catch(err => console.log(err))
}
render() {
return (
<div>
{ this.state.aaa}
</div>
);
}
}
export default Open;

You see this error since you are directly using state variable aaa in render function's return statement without telling react how to convert the aaa variable into JSX.
I have included aaa and and 1 more variable bbb. Depending upon what you want you can keep 1 variable remove the other one and its corresponding usage from your Open component.
import { Component } from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
class Open extends Component {
state = {
// state variable should be object if api response is object
aaa: {},
// if you only store 'listGetAllIndustry' then state variable should be array
bbb: []
};
componentDidMount() {
// I am assuming the api response to be this
const data = {
listGetAllJobAdvertisement: [],
listGetAllLocation: [
{ locationId: 1, city: "LOS ANGELES", country: "USA" },
{ locationId: 2, city: "LONDON", country: "ENGLAND" },
{ locationId: 3, city: "BERLIN", country: "GERMANY" }
],
listGetAllIndustry: [
{ industryId: 1, name: "ENERGY" },
{ industryId: 2, name: "MATERIALS" },
{ industryId: 3, name: "INDUSTRIALS" },
{ industryId: 4, name: "CONSUMER STAPLES" },
{ industryId: 5, name: "HEALTH CARE" },
{ industryId: 6, name: "FINANCIALS" },
{ industryId: 7, name: "INFORMATION TECHNOLOGY" },
{ industryId: 8, name: "COMMUNICATION SERVICES" },
{ industryId: 9, name: "UTILITIES" },
{ industryId: 10, name: "REAL ESTATE" }
]
};
// fetch(VacantPositions)
// .then(results => results.json())
// .then(data => this.setState({ aaa: data } ))
// .catch(err => console.log(err))
this.setState({
// keeping complete api response in the state
aaa: data || {},
// keeping only 'listGetAllIndustry' from api response in the state
bbb: data.listGetAllIndustry || []
});
}
render() {
return (
<div>
{this.state.aaa.listGetAllIndustry &&
this.state.aaa.listGetAllIndustry.map((industry) => {
return (
<div key={industry.industryId}>
<span>{industry.industryId}.</span>
<span>{industry.name}</span>
</div>
);
})}
===================================
{this.state.bbb.map((industry) => {
return (
<div key={industry.industryId}>
<span>{industry.industryId}.</span>
<span>{industry.name}</span>
</div>
);
})}
</div>
);
}
}
export default Open;

Your api is returning objects with multiple key and values you're setting that object into the state called 'aaa' , so you can't directly render a object in the return part you can render only particular value in the return method . You can use object.entries.map
{Object.keys(this.state.aaa).map(function(key, index) {
return (
<p>{key}</p>
<p>{index}</p>
)
})};
or you can specify the particular value like
render() {
return (
<div>
{ this?.state?.aaa?.listGetAllLocation[0]?.city}
</div>
);}

Related

Using find and map together React

We have chat app build on React
const Chat = ({ thread }) => {
return (
<div className='thread'>
{thread.map((message, index) =>
<Message message={message} key={index} repliedMessage={message}/>
)}
</div>
);
};
export default class App extends React.Component {
state = {
thread: [
{
id: 1,
user: 'John',
text: 'Hellow'
},
{
id: 2,
user: 'Jim',
replyTo: 1,
text: 'Hi'
},
{
id: 3,
user: 'Jack',
replyTo: 2,
text: 'Cheers :)'
}
]
};
App must show what message have been replied.
The question is - how I can use FIND method with MAP in Chat component?
I don't think you need to use the find method here:
thread.map((message, index) => {
if(message.replyTo) {
return ...
} else {
return ...
}
}
)

Gutenberg - Call google map render function in save after DOM has been rendered

I have a bit of a dilemma.
In the save function I need to call a function renderMap that renders a dynamic google map. However I need to call it after the DOM has been rendered. I can't seem to find a solution for this. I realised you can't add a class to the save function with the React lifecycle so I am stopped. It does work for the edit function though. What are the possibilities?
import { __ } from '#wordpress/i18n';
import { registerBlockType } from '#wordpress/blocks';
import { PluginDocumentSettingPanel } from '#wordpress/edit-post';
import { Component } from '#wordpress/element';
const renderMap = function() {
let googleMap = document.getElementById('google-map')
let map
map = new google.maps.Map(googleMap, {
center: { lat: 37.79406, lng: -122.4002 },
zoom: 14,
disableDefaultUI: true,
})
}
registerBlockType( 'splash-blocks/google-maps', {
title: __('Google maps locations', 'google-maps'),
icon: 'megaphone',
category: 'common',
keyword: [
__( 'Display Google maps locations' ),
],
atrributes: {
markers: {
type: 'object'
},
address: {
type: 'string',
default: 'xxxxxxxxx',
},
api_key: {
type: 'string',
default: 'xxxxxxxxx',
}
},
edit: class extends Component {
constructor(props) {
super(props)
}
componentDidMount() {
renderMap()
}
render() {
const { attributes, setAttributes } = this.props
return (
<div id='google-map'>
</div>
)
}
},
save: props => {
const {
className,
attributes: { mapHTML }
} = props;
renderMap()
return (
<div id='google-map'>
</div>
)
}
})

Migration to Mobx 6: functional components aren't working with decorated observables

I faced with problem while migrating from Mobx 4 to Mobx 6.
I have a functional component but after updating Mobx it stopped working. Looks like store doesn't works. Component react on changes inside observable variable by reaction feature but changes aren't re-rendering. I made everything that was provided in migration guide but component's store doesn't working.
At some reason if I change functional component to class component everything starts working. But I really can't understand the reason why such happens and can't find any explanation of such behaviour.
Case looks like example bellow. Experimental decorators are enabled and any other stuff that was provided in Migration guide as well. So what is the reason of such behaviour and how can I implement correct logic in functional component?
interface User {
name: string;
age: number;
info: {
phone: string;
email: string;
};
}
const usersData: User[] = [
{
name: "Steve",
age: 29,
info: {
phone: "+79011054333",
email: "steve1991#gmail.com",
},
},
{
name: "George",
age: 34,
info: {
phone: "+79283030322",
email: "george_the_best_777#gmail.com",
},
},
{
name: "Roger",
age: 17,
info: {
phone: "+79034451202",
email: "rodge_pirat_yohoho#gmail.com",
},
},
{
name: "Maria",
age: 22,
info: {
phone: "+79020114849",
email: "bunnyrabbit013#gmail.com",
},
},
];
const getUsers = () => {
return new Promise<User[]>((resolve) => {
setTimeout(() => {
resolve(usersData);
}, 2000);
});
};
class Store {
#observable users: User[] = [];
constructor() {
makeObservable(this);
}
async init() {
const users = await getUsers();
this.setUsers(users);
}
#action setUsers(users: User[]) {
this.users = users;
}
#action increaseUserAge(userIndex: number) {
const users = this.users.map((u, k) => {
if (k === userIndex) {
u.age += 1;
}
return u;
});
this.setUsers(users);
}
#computed get usersCount(): number {
return this.users.length;
}
}
const store = new Store();
const UserList = observer(() => {
React.useEffect(() => {
store.init();
}, []);
const addOneUser = () => {
const user = {
name: "Jesica",
age: 18,
info: {
phone: "+79886492224",
email: "jes3331#gmail.com",
},
};
store.setUsers([...store.users, user]);
};
return (
<div className="App">
<h4>Users: {store.usersCount}</h4>
{store.users.length ? (
<>
<ul>
{store.users.map((user, key) => (
<li key={key}>
Name: {user.name}, Age: {user.age}, Info:
<div>
Phone: {user.info.phone}, Email: {user.info.email}
</div>
<button onClick={() => store.increaseUserAge(key)}>
Increase Age
</button>
</li>
))}
</ul>
<button onClick={addOneUser} disabled={store.usersCount >= 5}>
Add one user
</button>
</>
) : (
<p>Fetching users...</p>
)}
</div>
);
});
function App() {
return <UserList />;
}
export default App;
I've made Codesandbox example with your code (although removed types), it works fine.
Check tsconfig.json there, maybe you forgot to enable some of the options?
Or check what versions of mobx and mobx-react are you using?
And just a small nitpick on how you use your increaseUserAge action, it can be as simple as that:
#action increaseUserAge(user) {
user.age += 1;
}
And in the jsx you just pass the whole user there:
<button onClick={() => store.increaseUserAge(user)}>
Increase Age
</button>

How to make a checkbox checked if a value exists in array of object in react

How can I make a checkbox checked if a value exists in array of object in reactjs ?
I have tried using includes function but it is not working.
I have array of object in employeeUnder key -
My array is -
"employeeUnder": [
{
"_id": "5d1a0a8a09b9cb0034d01aaf",
"employ": {
"_id": "5d120eba60093e02248d6a81",
"name": "Sehzan"
}
},
{
"_id": "5d1a0a8a09b9cb0034d01ab0",
"employ": {
"_id": "5d120eba60093e02248d6a83",
"name": "Sumit"
}
},
{
"_id": "5d1a0a8a09b9cb0034d01ab1",
"employ": {
"_id": "5d120eba60093e02248d6a7c",
"name": "Hariom"
}
}
],
I have to check if -
this.state.allemployees._id === employeeUnder.employ._id then checkbox must be checked.
My Code for input checkbox is -
if (this.state.allemployees && this.state.allemployees.length > 0) {
return (this.state.allemployees.map((employee) =>
<tr key={employee.empmainid}>
<td>{employee.empname}</td>
<td>{employee.empid}</td>
<td><input onChange={this.handleCheckbox} getUsername={employee.empname} className="" type="checkbox" checked name={employee.empmainid} value={employee.empmainid} /></td>
</tr>))
}
Right now all the checkbox are checked because I didn't apply the condition.
I want if a value exists in array of object then it must be checked otherwise NO.
Checkout this sandbox: https://codesandbox.io/s/blissful-edison-bjh0s
We'll be working with two arrays here:
allEmployees (never mutate)
employeesUnder (always update)
We can dynamically change the data inside employeesUnder through checking/toggling the corresponding input tag.
Essentially, inside the onChange() event, we will pass the id associated with an employee, if the input was already checked, that means it was already in the employeesUnder array. So we will use that id, to filter that employee out. The opposite would occur if the id was not found inside the array. So we would add the employee to employeesUnder.
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class App extends React.Component {
state = {
employeesUnder: [
{
_id: "5d1a0a8a09b9cb0034d01aaf",
employ: {
_id: "5d120eba60093e02248d6a81",
name: "Sehzan"
}
},
{
_id: "5d1a0a8a09b9cb0034d01ab0",
employ: {
_id: "5d120eba60093e02248d6a83",
name: "Sumit"
}
},
{
_id: "5d1a0a8a09b9cb0034d01ab1",
employ: {
_id: "5d120eba60093e02248d6a7c",
name: "Hariom"
}
}
],
allEmployees: [
{
_id: "3ds8f8ds9d8fds9f8a9f8afaf",
employ: {
_id: "eworweokrkowekoo34324234",
name: "Woofers"
}
},
{
_id: "5d1a0a8a09b9cb0034d01aaf",
employ: {
_id: "5d120eba60093e02248d6a81",
name: "Sehzan"
}
},
{
_id: "5d1a0a8a09b9cb0034d01ab0",
employ: {
_id: "5d120eba60093e02248d6a83",
name: "Sumit"
}
},
{
_id: "5d1a0a8a09b9cb0034d01ab1",
employ: {
_id: "5d120eba60093e02248d6a7c",
name: "Hariom"
}
}
]
};
handleCheck = id => {
const { allEmployees, employeesUnder } = this.state;
const employeesUnderIds = employeesUnder.map(employee => employee._id);
if (employeesUnderIds.includes(id)) {
//remove employee from employeesUnder list
const newArrWithRemovedEmployee = employeesUnder.filter(employee => {
return employee._id !== id;
});
this.setState({
...this.state,
employeesUnder: newArrWithRemovedEmployee
});
} else {
//add employee to employeesUnder list
const employeeIndex = allEmployees.findIndex(
employee => employee._id === id
);
const newArrWithAddedEmployee = [
...employeesUnder,
allEmployees[employeeIndex]
];
this.setState({
...this.state,
employeesUnder: newArrWithAddedEmployee
});
}
};
createList = () => {
const { allEmployees, employeesUnder } = this.state;
const employeesUnderIds = employeesUnder.map(employee => employee._id);
return allEmployees.map(employee => {
return (
<div>
<label>{employee.employ.name}: </label>
<input
type="checkbox"
value={employee._id}
checked={employeesUnderIds.includes(employee._id)}
onChange={() => this.handleCheck(employee._id)}
/>
</div>
);
});
};
render() {
return <div>{this.createList()}</div>;
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Pass total number of results from Yelp API call to React component

link to GitHub project: https://github.com/jkey774/codecademy-ravenous
I have been trying for a few days now to add a new feature to my little app that displays the total number of results for businesses retrieved from a Yelp API call. I can console.log(jsonResponse.total) just before mapping each business but am unsure how to set this up in the return statement to where jsonResponse.total from Yelp.js can be accessed in App.js to do something like setState({ total: total }). Do I need to make a separate API call just to get the total?
here is an example of what the response body looks like:
{
"total": 8228,
"businesses": [
{
"rating": 4,
"id": "E8RJkjfdcwgtyoPMjQ_Olg",
"review_count": 1738,
"name": "Four Barrel Coffee",
"image_url": "http://s3-media2.fl.yelpcdn.com/bphoto/MmgtASP3l_t4tPCL1iAsCg/o.jpg",
"location": {
"city": "San Francisco",
"state": "CA",
"address1": "375 Valencia St",
"zip_code": "94103"
}
},
// ...
]
}
in my Yelp.js file:
const Yelp = {
search(term, location, sortBy) {
const limit = 21;
return fetch(`https://cors-anywhere.herokuapp.com/https://api.yelp.com/v3/businesses/search?term=${term}&location=${location}&sort_by=${sortBy}&limit=${limit}`, {
headers: {
Authorization: `Bearer ${apiKey}`
}
}).then(function (response) {
return response.json();
}).then(function (jsonResponse) {
if (jsonResponse.businesses) {
return jsonResponse.businesses.map(function (business) {
return {
id: business.id,
imageSrc: business.image_url,
name: business.name,
address: business.location.address1,
city: business.location.city,
state: business.location.state,
zipCode: business.location.zip_code,
category: business.categories[0].title,
rating: business.rating,
reviewCount: business.review_count
};
});
}
});
}
};
export default Yelp;
in my App.js file
import React from 'react';
import BusinessList from './components/BusinessList/BusinessList';
import SearchBar from './components/SearchBar/SearchBar';
import Yelp from './util/Yelp';
import './App.css';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
total: 0,
businesses: []
}
this.searchYelp = this.searchYelp.bind(this);
}
searchYelp(term, location, sortBy) {
Yelp.search(term, location, sortBy).then((businesses) => {
this.setState({
businesses: businesses
})
})
}
render() {
return (
<div className="App">
<h1>ravenous</h1>
<SearchBar searchYelp={this.searchYelp} />
<BusinessList businesses={this.state.businesses} />
</div>
);
}
}
export default App;
Welcome to Stack Overflow. As you mentioned, you can set multiple keys in a single call to setState, so all you have to do is get the total to your App.js.
In Yelp.js you need to return the total along with the list of businesses. You could do something like:
if (jsonResponse.businesses) {
return {
total: jsonResponse.total,
businessList: jsonResponse.businesses.map(function (business) {
// ... same code as you have before
Then, rework your setState just a little bit in App.js:
Yelp.search(term, location, sortBy).then((businessData) => {
this.setState({
businesses: businessData.businessList,
total: businessData.total
})
})

Resources