how to fetch data using assignment or function in react - javascript

I have a component where I fetch data:
here is my code :-
class HomePage extends Component{
constructor(props) {
super(props)
this.state = {
eminem: []
}
}
url = "https://deezerdevs-deezer.p.rapidapi.com/search?q=";
componentDidMount = () => {
fetch(this.url + "eminem", {
"method": "GET",
"headers": {
"Accept": "application/json",
"x-rapidapi-host": "deezerdevs-deezer.p.rapidapi.com",
"x-rapidapi-key": [key]
}
})
.then((response) => response.json())
.then((responseObject) => {
console.log(responseObject);
this.setState({ eminem : responseObject})
}
)
.catch((err) => {
this.setState({ error: true });
console.log('An error occucred:', err);
})
}
render(){
return(
<>
<div className="col-12 col-md-9 offset-md-3 mainPage">
<div className="row">
<div className="col-9 col-lg-11 mainLinks d-none d-md-flex">
TRENDING
PODCAST
MOODS AND GENRES
NEW RELEASES
DISCOVER
</div>
</div>
<div className="row">
<div className="col-10">
<div id="rock">
<h2>Eminem</h2>
<div className='row'>
{ this.state.eminem.data.forEach(item => {
<div className='col-3'>{item.title}</div>
})}
</div>
</div>
</div>
</div>
</div>
</>
)
}
}
But I've got an error: Expected an assignment or function call and instead saw an expression no-unused-expressions. I can't understand what I've missed. And give me advice what do I have to understand in react to avoid such mistakes. Cause I'm a newcomer in react world and wanna understand all the concepts.

hi can just replace your componentDidMount handler with below one and try if it's solving your problem or not because what I think that you use inappropriate formate for defining that method
componentDidMount () {
fetch(this.url + "eminem", {
"method": "GET",
"headers": {
"Accept": "application/json",
"x-rapidapi-host": "deezerdevs-deezer.p.rapidapi.com",
"x-rapidapi-key": [key]
}
})
.then((response) => response.json())
.then((responseObject) => {
console.log(responseObject);
this.setState({ eminem : responseObject})
}
)
.catch((err) => {
this.setState({ error: true });
console.log('An error occucred:', err);
})
}
and also return the element from the loop like this
{ this.state.eminem.data.map(item => <div className='col-3'>{item.title}</div>)}

First : As your initial state looks like this :
this.state = {
eminem: []
}
If you are getting your data inside responseObject.data then change this
this.setState({ eminem : responseObject})
To :
this.setState({ eminem : responseObject.data })
Second :
Because you are not returning anything from loop, first you need to change forEach to map and then you need to return JSX from it.
Change this :
{
this.state.eminem.data.forEach(item => {
<div className='col-3'>{item.title}</div>
})
}
To :
{
this.state.eminem.map(item => { // <--- map
return <div className='col-3'>{item.title}</div> // <--- Return
})
}
OR (shorter version)
{
this.state.eminem.map(item => <div className='col-3'>{item.title}</div>)
}

Related

facing error of bad request even thought the query is same

Well i am trying to reduce the line of code at once refactoring the code
import React, { Component } from 'react';
import { Loader } from '../../components';
import './ProductListing.scss';
import { ProductCard } from '../../components';
import { productQuery } from '../../utls/queries';
export class ProductListing extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
products: [],
categoryId: '',
};
}
componentDidMount() {
const currentUrl = window.location.pathname;
const id = currentUrl.replace('/', '');
this.setState({ categoryId: id });
const newQuer = { ...productQuery };
const query = `
query{
categories {
name
products {
id,
name,
brand,
inStock,
gallery,
category,
prices {
amount,
currency {
label,
symbol
}
}
}
}
}
`;
console.log(query === productQuery);
console.log(productQuery);
fetch('http://localhost:4000', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify({
query,
}),
})
.then((response) => {
return response.json();
})
.then((data) => {
this.setState({
products: data.data,
loading: false,
});
});
}
render() {
if (this.state.loading === true) {
return <Loader />;
} else {
return (
<div>
<h2 className='page__listing__title'>
{this.state.categoryId[0].toUpperCase() +
this.state.categoryId.substring(1)}
</h2>
<div className='productlisting__page'>
{this.state.products.categories.map((item, index) => (
<div key={index}>
{item.name === this.state.categoryId ? (
<div className='product__listing__card'>
{item.products.map((product, i) => (
<ProductCard product={product} key={i} />
))}
</div>
) : (
''
)}
</div>
))}
</div>
</div>
);
}
}
}
export default ProductListing;
In the process of reducing code i see that the query is taking a lot of places so i decided to write it at separate place now i am importing it as productQuery when i console.log(productQuery===query) it says true but the place where i am using the query to fetch data i use productQuery it just give bad error i cant understand ...
if some one have much better idea i really like if you can suggest me much better ways by which i can reduce the lines of code
I think what's happening is you're accidentally destructuring the query you import, when you say
const newQuery = {...productQuery}
productQuery is simply a string (as proven by your console log that stays productQuery === query).
newQuery is an object that destructures the string, and trying to use that would likely result in a failure.

How to get HTML tag from API response in React Js?

I have a response from Api like the following:
data: {
id : 20,
name : "Michael",
content : "Today is <p>my special day in my life</p> thankyou"
}
and in react code as follows:
const dataMain = useselector((state) => state.main.data)
return (
<>
<div>
<div className="name"><h2>{dataMain.name}</h2></div>
<div className="the-content" dangerouslySetInnerHTML={{__html: dataMain.content></div>
</div>
</>
)
Result :
Michael,
Today is <p>my special day in my life</p> thankyou
The html P tag is still there, while I want it to disappear
When setting your content in dangerouslySetInnerHTML try ${dataMain.content} otherwise set the value to state variable using ${} syntax. This has worked for me on other compnents with HTML tags.
Example below:
class ExampleComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoaded: false,
content: null
}
}
componentDidMount() {
const payload = {};
fetch("/example",{
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
})
.then((response) => {
return response.text();
})
.then((text) => {
this.setState({
isLoaded: true,
content: `${text}`
});
});
}
render() {
return (
<React.Fragment>
{!this.state.isLoaded &&
<div className="text-info">
Please wait...
</div>
}
{this.state.isLoaded &&
<div id="terms-content" dangerouslySetInnerHTML={{__html: this.state.content}}/>
}
</React.Fragment>
)
}
}

How to POST data from this.state?

I'm trying to use this.state in a POST call with Axios, and I can't understand why it isn't working. I tried to connect (getting a "bind () is not a function" error) and setState, but nothing seems to work . I can't find any good solution for this problem, follow the code below, thanks for your help in advance!
import ReactDOM from 'react-dom';
import axios from 'axios';
class AccountSettings extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
projects: "Loading...",
};
}
componentDidMount() {
fetch("/../api/****/account/projects")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
projects: result
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
saveProjects(event) {
axios.post('/../api/****/account/projects/save',{
projects: this.state.projects,
})
.then()
.catch();
event.preventDefault();
}
handleOnChange(event) {
this.setState({
projects: event.target.value
})
}
render() {
return (
<form method="post" onSubmit={this.saveProjects}>
<label htmlFor="projectsInput">My projects</label>
<textarea className="form-control" id="projectsInput" rows="3" aria-describedby="projectsInputHelp"
name="projectsInput" value={this.state.projects}
onChange={(event) => this.handleOnChange(event)} />
<small id="projectsInputHelp" className="form-text text-muted">
Add every project on a new line.<br/><br/>
</small>
<button type="submit" className="btn btn-primary">
Save projects
</button>
</form>
)
}
}
ReactDOM.render(<AccountSettings />, document.getElementById("account-settings"));```
Binding works for me this.saveProjects=this.saveProjects.bind(this); and if somehow binding fails then you can always use arrow functions in class components.
I'm doing this:
let data = Object.keys(this.state.fields).map(key => encodeURIComponent('formName['+key+']') + '=' + encodeURIComponent(this.state.fields[key])).join('&'))
fetch('....', {
method: "POST",
body: data,
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Accept': 'application/json, text/javascript, */*',
'X-Requested-With': 'XMLHttpRequest' <--- if needed for php framework isXmlHTTPRequest()
}
})
.then( response => response.json() )
.then( json => {
console.log(json);
})
.catch(error => console.log(error))

Set input value automatically on a fetch request

I present my problem to you
In the following code, I'm trying to retrieve phone numbers from an API and then show them in a Card; in each card, I have a different number which is displayed
and also in each card, I have an input field to enter the phone number which I obtained before.
My problem is that I don't want to fill in the input manually with the recovered number.
So basically I would like to start my function without having to fill in this field manually.
Do you have any idea how to do this?
I tried to simplify the code so that it is as clear as possible
Thanks for your help Neff
import React, { Component } from 'react';
import { CardText, Card,Row, Col, CardTitle, Button } from 'reactstrap';
import axios from 'axios'
const entrypoint = process.env.REACT_APP_API_ENTRYPOINT+'/api';
class AdminPage extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
message: {
to: '',
body: 'hola amigo :)'
},
submitting: false,
error: false
};
this.onHandleChange = this.onHandleChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
onSubmit(event) {
event.preventDefault();
this.setState({ submitting: true });
fetch('/api/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(this.state.message)
})
.then(res => res.json())
.then(data => {
if (data.success) {
this.setState({
error: false,
submitting: false,
message: {
to: '',
body: ''
}
});
} else {
this.setState({
error: true,
submitting: false
});
}
});
}
// rest of the component
onHandleChange(event) {
const name = event.target.getAttribute('name');
this.setState({
message: { ...this.state.message, [name]: event.target.value }
});
}
getRandom = async () => {
const res = await axios.get(
entrypoint + "/alluserpls"
)
this.setState({ data: res.data })
}
componentDidMount() {
this.getRandom()
}
render() {
let datas = this.state.data.map(datass => {
const status = JSON.parse(localStorage.getItem("validated-order")||"{}")[datass.id];
return (
<div>
< Col sm="12" key={datass.id} className="wtfFuHereIsForOnlyBackGroundColorForCol12Nice">
<div key="a">
<Card body className="yoloCardBody">
<CardText> Téléphone {datass.phone}</CardText>
<form
onSubmit={this.onSubmit}
className={this.state.error ? 'error sms-form' : 'sms-form'} >
<div>
<input
type="tel"
name="to"
id="to"
value={this.state.message.to}
onChange={this.onHandleChange}
/>
</div>
<Button className="buttonForLancerMaybe" type="submit" disabled=
{this.state.submitting}>SMS</Button>
</form>
</Card>
</div>
</Col>
</div>
)
})
return (
<div> <div>
<div>
{datas}
</div>
</div>
</div>
<div className="box">
</div>
</div>
)
}
}
export default AdminPage
So I guess this little change in your code will help you, separating the logic and making a new component for your form section would be your solution. say we have a component called "SmsForm" so first, you need to import it in your current component:
import SmsForm from "../SmsForm/Loadable";
and then you pass your phone number as a prop to this SmsForm like this:
let datas = this.state.data.map(datass => {
const status = JSON.parse(localStorage.getItem("validated-order") || "{}")[datass.id];
return (
<div>
< Col sm="12" key={datass.id} className="wtfFuHereIsForOnlyBackGroundColorForCol12Nice">
<GridLayout className="GridlayoutTextOnlyForGridOuiAndHeigthbecauseHeigthWasBug" layout={layout} cols={12} rowHeight={30} width={1200}>
<div key="a">
<Card body className="yoloCardBody">
<CardText> Téléphone {datass.phone}</CardText>
<SmsForm phone={datass.phone}/>
</Card>
</div>
</GridLayout>
</ Col>
</div>
)
})
and SmsForm would be sth like this:
import React from 'react';
...
export class SmsForm extends React.Component {
constructor(props) {
super(props);
this.state = {
message: {
to: props.phone,
body: 'hola amigo :)'
},
submitting: false,
error: false
};
this.onHandleChange = this.onHandleChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
onSubmit(event) {
event.preventDefault();
this.setState({ submitting: true });
fetch('/api/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(this.state.message)
})
.then(res => res.json())
.then(data => {
if (data.success) {
this.setState({
error: false,
submitting: false,
message: {
to: '',
body: ''
}
});
} else {
this.setState({
error: true,
submitting: false
});
}
});
}
// rest of the component
onHandleChange(event) {
const name = event.target.getAttribute('name');
this.setState({
message: { ...this.state.message, [name]: event.target.value }
});
}
render() {
return (
<form
onSubmit={this.onSubmit}
className={this.state.error ? 'error sms-form' : 'sms-form'} >
<div>
<input type="tel" name="to" id="to" value={datass.phone} onChange={e => this.onHandleChange(e, e.target.value)}/>
</div>
<Button className="buttonForLancerMaybe" type="submit" disabled=
{this.state.submitting}>SMS</Button>
</form>
);
}
}
export default SmsForm;

How to automatically change text depending on boolean value in JSON file

I have a JSON file:
[
{
"id": 1,
"text": "Hello",
"availability": false
},
{
"id": 2,
"text": "Hello",
"availability": true
}
]
What I would like to achieve is for the text to automatically change from hello to goodbye when availability : false. If availability : true then I would like it to stay the same displaying 'Hello'.
This is my code so far:
import React, { Component } from 'react';
import './styles.css'
class GetOnlinePosts extends Component {
constructor(props){
super(props);
this.state = {
error : null,
isLoaded : false,
posts : []
};
}
componentDidMount(){
fetch("https://api.myjson.com")
.then( response => response.json())
.then(
(result) => {
this.setState({
isLoaded : true,
posts : result
});
},
(error) => {
this.setState({
isLoaded: true,
error
})
},
)
}
render() {
const {error, isLoaded, posts} = this.state;
const orderedPosts = [...posts.filter((post) => post.availability), ...posts.filter((post) => !post.availability)]
if(error){
return <div>Error in loading</div>
}else if (!isLoaded) {
return <div>Loading ...</div>
}else{
return(
<div>
<div className="tiles">
{
orderedPosts.map(post => (
<div key={post.id}>
<div className="tile">
<p className="greeting">{post.text}</p>
</div>
</div>
))
}
</div>
</div>
);
}
}
}
export default GetOnlinePosts;
Any help on changing the text from 'Hello' to 'Goodbye' when availability : false and keeping the text 'Hello' when availability : true would be great. thanks in advance
Please add condition to map
<p className="greeting">{post.availability ? post.text : 'Goodbye'}</p>
Please changes this line
import React, { Component } from 'react';
import './styles.css'
class GetOnlinePosts extends Component {
constructor(props){
super(props);
this.state = {
error : null,
isLoaded : false,
posts : []
};
}
componentDidMount(){
fetch("https://api.myjson.com")
.then( response => response.json())
.then(
(result) => {
this.setState({
isLoaded : true,
posts : result
});
},
(error) => {
this.setState({
isLoaded: true,
error
})
},
)
}
render() {
const {error, isLoaded, posts} = this.state;
const orderedPosts = [...posts.filter((post) => post.availability), ...posts.filter((post) => !post.availability)]
if(error){
return <div>Error in loading</div>
}else if (!isLoaded) {
return <div>Loading ...</div>
}else{
return(
<div>
<div className="tiles">
{
orderedPosts.map(post => (
<div key={post.id}>
<div className="tile">
<p className="greeting">{post.availability ? post.text : 'Goodbye'}</p> // Change this line
</div>
</div>
))
}
</div>
</div>
);
}
}
}
export default GetOnlinePosts;
Somewhere after fetching, map the results like this:
const processPost = post => post.availability
? post
: Object.assign({}, post, { text: "Goodbye" });
// ...
fetch("https://api.myjson.com")
.then(response => response.json())
.then(posts => posts.map(processPost))
This is easy to achieve with simple ternary statement.
return(
<div>
<div className="tiles">
{
orderedPosts.map(post => (
<div key={post.id}>
<div className="tile">
<p className="greeting">{post.availability ? post.text : 'Goodbye!'}</p>
</div>
</div>
))
}
</div>
</div>
);
Docs for ternary: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
You can use ternary operator for displaying text.I hope it will helps you.
import React, { Component } from 'react';
import './styles.css'
class GetOnlinePosts extends Component {
constructor(props){
super(props);
this.state = {
error : null,
isLoaded : false,
posts : []
};
}
componentDidMount(){
fetch("https://api.myjson.com")
.then( response => response.json())
.then(
(result) => {
this.setState({
isLoaded : true,
posts : result
});
},
(error) => {
this.setState({
isLoaded: true,
error
})
},
)
}
render() {
const {error, isLoaded, posts} = this.state;
const orderedPosts = [...posts.filter((post) => post.availability), ...posts.filter((post) => !post.availability)]
if(error){
return <div>Error in loading</div>
}else if (!isLoaded) {
return <div>Loading ...</div>
}else{
return(
<div>
<div className="tiles">
{
orderedPosts.map(post => (
<div key={post.id}>
<div className="tile">
{
post.availability:( <p className="greeting">{post.text}</p>)?
(<p className="greeting">Goodbye</p>)
}
</div>
</div>
))
}
</div>
</div>
);
}
}
}
export default GetOnlinePosts;

Categories

Resources