React JS Axios map - reactjs

I have 4 components in my project, that have the APIs, and there information.
the App.js includes the APIs:
This is in my Country.js Component
render() {
const DataGroup = this.props.countries.map((county) => {
return <InfoData info={county} />;
});
const DataGroupAll = this.props.countriesAll.map((country) => {
return <InfosData infos={country} />;
});
return (
<div>
{DataGroup}
{DataGroupAll}
</div>
);
}
and the InfoData.js
<div class="card-columns">
<div class="card-body">
<h5 class="card-title">Date : {this.props.info.updated_at}</h5>
<p class="card-text">Confirmed : {this.props.info.today.confirmed}</p>
<p class="card-text">Deaths : {this.props.info.today.deaths}</p>
</div>
</div>
and the InfosData.js
<div class="card-deck">
<div class="card">
<img src={this.props.infos.flag} width="180" height="130" />
<div class="card-body">
<h4 class="card-title">Name : {this.props.infos.name}</h4>
<p class="card-text">Capital : {this.props.infos.capital}</p>
<p class="card-text">
Currency :
{this.props.infos.currencies.map((country) => {
return country.code;
})}
</p>
<p class="card-text">
Languages :
{this.props.infos.languages.map((country) => {
return country.name + ',';
})}
</p>
<p class="card-text">Timezones : {this.props.infos.timezones}</p>
</div>
</div>
</div>
but all the information I got will be in separate cards, how can I combine them by the country code ?

Related

Browser URL updates but components do not update

I have a problem. Link in component change Url in browser but not return component until i reload my browser.
I click product detail. Inside product detail have similar product.
I click on product details of similar products.
-> Browser Url update but it doesn't return product details until I reload the browser.
This is product in home:
<div className="col-md col-6">
<figure className="card-product-grid card-sm">
<Link to={`product-detail/${item.id}`} className="img-wrap item">
<img src={img_path + item.image} alt="null" />
</Link><div className="text-wrap p-3">{item.productName}
<span className="badge badge-danger"> {item.salePrice * 100 / item.price}
</span>
</div>
</figure>
</div>
This is similar product:
{productLike && productLike.length > 0 && productLike.map((item, index) => {
return <>
<Product key={index} id={item.id} image={item.image} productName={item.productName} detail={item.detail} price={item.price} />
This is Product component:
import React from "react";
import { Link } from "react-router-dom";
class Product extends React.Component {
render() {
var img_path = "http://localhost:8000/img/"
return (
<div class="col-md-3">
<figure class="card card-product-grid">
<div class="img-wrap">
<img src={img_path + this.props.image} alt="null" />
</div>
<figcaption class="info-wrap">
<h6 class="title" >{this.props.productName}</h6>
<Link to={`/product-detail/${this.props.id}`} class="title mb-2">{this.props.detail.indexOf('</') !== -1
? (
<div dangerouslySetInnerHTML={{ __html: this.props.detail.replace(/(<? *script)/gi, 'illegalscript') }} >
</div>
)
: this.props.detail
}</Link>
<div class="price-wrap">
<span class="price">{this.props.price}</span>
<small class="text-muted">/per bag</small>
</div>
<p class="mb-2"> 2 Pieces <small class="text-muted">(Min Order)</small></p>
<p class="text-muted ">Guangzhou Yichuang Electronic Co</p>
<hr />
<label class="custom-control mb-3 custom-checkbox">
<input type="checkbox" class="custom-control-input" />
<div class="custom-control-label">Add to compare
</div>
</label>
<i class="fa fa-envelope"></i> Contact supplier
</figcaption>
</figure>
</div>
);
}
}
export default Product;
Can someone help? Thank!

loop through api json data react js

i konw there are similar question to this but i couldn't find the solution.
i'm trying to loop through this "div" with data coming from django rest api (JSON format)
async componentDidMount() {
const response = await fetch('/api/Post');
const data = await response.json();
this.setState({
posts: data.data[0],
loading: false
});
}
<div class="row">
<div class="col-md-6 col-6 paddding animate-box" data-animate-effect="fadeIn">
<div class="fh5co_suceefh5co_height_2"><img src={image} alt="img"/>
<div class="fh5co_suceefh5co_height_position_absolute"></div>
<div class="fh5co_suceefh5co_height_position_absolute_font_2">
<div class=""> <i class="fa fa-clock-o"></i> {date_posted} </div>
<div class=""> {title} </div>
</div>
</div>
</div></div>
i tried to use "map" but i'm not sure how
function renderposts() {
const postList = [];
for(let i = 0; i < this.state.posts.length; i++) {
let title = `${this.state.posts[i].title}`;
let image = this.state.posts[i].image;
let date_posted = this.state.posts[i].date_posted;
let key = this.state.posts[i].id.value;
postList.push(<Post
<div class="row">
<div class="col-md-6 col-6 paddding animate-box" data-animate-effect="fadeIn">
<div class="fh5co_suceefh5co_height_2"><img src={image} alt="img"/>
<div class="fh5co_suceefh5co_height_position_absolute"></div>
<div class="fh5co_suceefh5co_height_position_absolute_font_2">
<div class=""> <i class="fa fa-clock-o"></i> {date_posted} </div>
<div class=""> {title} </div>
</div>
</div>
</div></div>
/>);
}
return postList;
}
try like this in your render method:
{this.state.posts.map((post) => {
return (
<div
class="col-md-6 col-6 paddding animate-box"
data-animate-effect="fadeIn"
>
<div class="fh5co_suceefh5co_height_2">
<img src={post.image} alt="img" />
<div class="fh5co_suceefh5co_height_position_absolute"></div>
<div class="fh5co_suceefh5co_height_position_absolute_font_2">
<div class="">
<a href="#" class="color_fff">
{" "}
<i class="fa fa-clock-o"></i> {post.date_posted}{" "}
</a>
</div>
<div class="">
<a href="single.html" class="fh5co_good_font_2">
{" "}
{post.title}{" "}
</a>
</div>
</div>
</div>
</div>
);
})}
here is a codesandbox example using hooks:
codesandbox
I assume that data.data[0] is an array of data. In React, when you want to loop through a array of data, always use method that return a clone of your data such as map or filter to avoid problem with immutability. Here's the specific code for your problem:
const postList = this.state.posts.map((post) => {
// Destructuring assignment
const { title, image, date_posted } = post;
const key = post.id.value;
return (
<div class="row">
<div
class="col-md-6 col-6 paddding animate-box"
data-animate-effect="fadeIn"
>
<div class="fh5co_suceefh5co_height_2">
<img src={image} alt="img" />
<div class="fh5co_suceefh5co_height_position_absolute"></div>
<div class="fh5co_suceefh5co_height_position_absolute_font_2">
<div class="">
<a href="#" class="color_fff">
{' '}
<i class="fa fa-clock-o"></i> {date_posted}{' '}
</a>
</div>
<div class="">
<a href="single.html" class="fh5co_good_font_2">
{' '}
{title}{' '}
</a>
</div>
</div>
</div>
</div>
</div>
);
});

React - How to pass props down for the .map function when using functional components

How can I pass the props from the ProductFeatures to the renderFeatures function ?
Below is a sample code:
const renderFeatures = (feature) => {
return (
<div key={feature.productFeatureTypeId} className="panel panel-default">
<div className="panel-heading">
<div className="row row-no-border row-h-10">
<div className="col-xs-10">
<a
className="accordion-toggle"
data-toggle="collapse"
href={"#" + feature.productFeatureTypeId}
>
<h4 className="panel-title">{feature.productFeatureTypeId}</h4>
</a>
</div>
<div className="col-xs-2 text-right font-size-16">
<span className="glyphicon glyphicon-circle-arrow-down"></span>
</div>
</div>
</div>
<div
id={feature.productFeatureTypeId}
className="panel-collapse collapse in"
>
<div className="panel-body">
{feature.productFeaturesDescription.map(renderFeatureObjItem)}
</div>
</div>
</div>
);
};
const ProductFeatures = (props) => {
let mappedProductFeaturesMembers = getMappedProductFeaturesMembers(
props.product.productFeatureMembers
);
return (
<div className="panel-group" id="accordion">
{mappedProductFeaturesMembers.map(renderFeatures)}
</div>
);
};
Note that all this code is inside one file named ProductFeatures.js and I am using functional components.
You can just pass it in the rednerFeatures like this:
const renderFeatures = (feature, props) => { // Accept both feature and props
return (
<div key={feature.productFeatureTypeId} className="panel panel-default">
<div className="panel-heading">
<div className="row row-no-border row-h-10">
<div className="col-xs-10">
<a
className="accordion-toggle"
data-toggle="collapse"
href={"#" + feature.productFeatureTypeId}
>
<h4 className="panel-title">{feature.productFeatureTypeId}</h4>
</a>
</div>
<div className="col-xs-2 text-right font-size-16">
<span className="glyphicon glyphicon-circle-arrow-down"></span>
</div>
</div>
</div>
<div
id={feature.productFeatureTypeId}
className="panel-collapse collapse in"
>
<div className="panel-body">
{feature.productFeaturesDescription.map(renderFeatureObjItem)}
</div>
</div>
</div>
);
};
const ProductFeatures = (props) => {
let mappedProductFeaturesMembers = getMappedProductFeaturesMembers(
props.product.productFeatureMembers
);
return (
<div className="panel-group" id="accordion">
{mappedProductFeaturesMembers.map(feature => renderFeatures(feature, props))} // Pass props here too
</div>
);
};

Rendering list of items with ReactJS

I've stumbled upon a trouble with rendering list items inside the component. What am I doing wrong and how to fix it?
This is what I've got in state
this.state = {
tasksState: false,
cupsState: false,
...
citizensData: [
{
diamsEarned: 5,
rubiesEarned: 6,
}, ...
]
}
Throphies are given as props
<Citizens tasksState={this.state.tasksState}
cupsState={this.state.cupsState}
trophies={this.state.citizensData} />
const Citizens = (props) => {
let {
tasksState,
cupsState,
trophies
} = {...props};
let CitizensList = [];
for (let i=0; i<20; i++) {
CitizensList.push(
<div className="Citizens__container--block">
<div className="box label-box">
<label className="label-ct" htmlFor="citiz">Citizen {i+1}:</label>
</div>
...
<div className="box diamond-box">
<i className="fas fa-gem icon icon-diamond"></i>
<p>{trophies[i].diamsEarned}</p>
</div>
<div className="box ruby-box">
<i className="fas fa-gem icon icon-ruby"></i>
<p>{trophies[i].rubiesEarned}</p>
</div>
);
}
return (
<div className="Citizens">
<div className="Citizens__container">
<CitizensList />
</div>
</div>
);
}
As a result, list ain't rendered at all
You can replace this line:
<CitizensList />
with this:
{[...Array(20)].map(i => (
<div className="Citizens__container--block" key={i}>
<div className="box label-box">
<label className="label-ct" htmlFor="citiz">Citizen {i+1}:</label>
</div>
...
<div className="box diamond-box">
<i className="fas fa-gem icon icon-diamond"></i>
<p>{trophies[i].diamsEarned}</p>
</div>
<div className="box ruby-box">
<i className="fas fa-gem icon icon-ruby"></i>
<p>{trophies[i].rubiesEarned}</p>
</div>
</div>
))}
Though I recommend creating a component for the citizen.
In react it better to use components, more components more flexibility. If I were to do the same task I would create another functional component for your
CitizensList
yet you can follow the below approach,
Here i = number of iteration and also you are missing a closing div.
const Citizens = (props) => {
let {
tasksState,
cupsState,
trophies
} = {...props};
let i = 20;
return (
<div className="Citizens">
<div className="Citizens__container">
{
Array.from(Array(i)).map((j) =>
<div className="Citizens__container--block">
<div className="box label-box">
<label className="label-ct" htmlFor="citiz">Citizen {j+1}:</label>
</div>
...
<div className="box diamond-box">
<i className="fas fa-gem icon icon-diamond"></i>
<p>{trophies[j].diamsEarned}</p>
</div>
<div className="box ruby-box">
<i className="fas fa-gem icon icon-ruby"></i>
<p>{trophies[j].rubiesEarned}</p>
</div>
</div>
))
}
</div>
</div>
);
}

Change fields names in React

I currently have this code, and in a spam it calls {image.processamento.result}
renderImgs() {
const { images, loadingFetchImages } = this.state;
if (loadingFetchImages) {
return <Loading />;
}
return images.map(image => (
<div key={image.processamento.id} className="col-2">
<div role="button" tabIndex={0} onKeyPress={() => this.checkImage(image.processamento.id)} onClick={() => this.checkImage(image.processamento.id)} className={`lista-img-validar ${image.check ? 'active' : ''}`}>
<figure>
<img src={image.public_url} id="image-authorize" className="img-responsive" alt="Imagem da prova" />
</figure>
<figcaption>
<div className="col-12">
<article className="text-left">
<span className="validador-txt-destaque">{image.processamento.co_inscricao}</span>
</article>
</div>
<div className="col-12">
<article className="text-left mt-2">
<span className="validador-txt-destaque-silver">Lote: </span>
<span>{image.processamento.batch}</span>
</article>
</div>
<div className="col-12">
<article className="text-left mt-2">
<span className="validador-txt-destaque-silver">Situação: </span>
<span>{image.processamento.result}</span>
</article>
</div>
</figcaption>
</div>
</div>
));
}
{image.processamento.result} can return 3 values, "essay", "inssuficient" and "blank", all that I want to do is change this names when I'm rendering the images to the user, for ex. I want that "blank" becomes "Sem texto."
I'm confused because inside a return I can't use conditionals like if else etc, can someone help me?
renderImgs() {
const { images, loadingFetchImages } = this.state;
if (loadingFetchImages) {
return <Loading />;
}
const getFriendlyName = function(name) {
if(name == "blank"){
return "Sem texto
}
return name
}
return images.map(image => (
<div key={image.processamento.id} className="col-2">
<div role="button" tabIndex={0} onKeyPress={() => this.checkImage(image.processamento.id)} onClick={() => this.checkImage(image.processamento.id)} className={`lista-img-validar ${image.check ? 'active' : ''}`}>
<figure>
<img src={image.public_url} id="image-authorize" className="img-responsive" alt="Imagem da prova" />
</figure>
<figcaption>
<div className="col-12">
<article className="text-left">
<span className="validador-txt-destaque">{image.processamento.co_inscricao}</span>
</article>
</div>
<div className="col-12">
<article className="text-left mt-2">
<span className="validador-txt-destaque-silver">Lote: </span>
<span>{image.processamento.batch}</span>
</article>
</div>
<div className="col-12">
<article className="text-left mt-2">
<span className="validador-txt-destaque-silver">Situação: </span>
<span>{getFriendlyName(image.processamento.result)}</span>
</article>
</div>
</figcaption>
</div>
</div>
));
}
Do like this.
<span>{image.processamento.result == "blank" ? "Sem texto" : image.processamento.result }</span>
You could do this from many ways, I think the right way you can do this:
const status = [
blank:"some blank text",
essay:"some essay text",
inssuficient:"some inssuficient text"
];
<span>{status[image.processamento.result]}</span>
Ternary operators are essential in JSX. They can also be chained, much like if/elses,
This would be valid:
<span>{image.processamento.result === 'blank' ? "Sem texto" : image.processamento.result === 'insufficient' ? 'Não suficiente' : image.processamento.result }</span>
Of course, this can all be abstracted before returning the jsx tag into if statements. Inside your map, instead of a shorthand return, you would just do an explicit return, and declare a variable representing the result before that. But that's really just a matter of preference.

Resources