Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
81
rated 0 times [  86] [ 5]  / answers: 1 / hits: 5776  / 5 Years ago, sat, june 15, 2019, 12:00:00

I am developing Currency Converter application using ReactJS. The program is about convert from one currency to another. The application has one form consist of a field with submit button. Moreover it also has initial currency 'USD 10' as a default.



When user type the an abbreviation of currency (e.g.: KRW) in the field and click the submit button. There will be a result below the form that shows the result of the conversion from USD to KRW. If the user want to add more currency, another selection currency will be shown below KRW conversion result.



When I am trying to make function to show the result when user submit the abbreviation of currency in the field.



This is the error:



Uncaught (in promise) TypeError: Cannot read property 'rates' of undefined
at Currency.render (App.js:402)
at finishClassComponent (react-dom.development.js:15319)
at updateClassComponent (react-dom.development.js:15274)
at beginWork (react-dom.development.js:16262)
at performUnitOfWork (react-dom.development.js:20279)
at workLoop (react-dom.development.js:20320)
at renderRoot (react-dom.development.js:20400)
at performWorkOnRoot (react-dom.development.js:21357)
at performWork (react-dom.development.js:21267)
at performSyncWork (react-dom.development.js:21241)
at requestWork (react-dom.development.js:21096)
at scheduleWork (react-dom.development.js:20909)
at Object.enqueueSetState (react-dom.development.js:11595)
at App.push../node_modules/react/cjs/react.development.js.Component.setState (react.development.js:336)
at Object.App.addCurrency [as onSubmit] (App.js:34)
at Form.handleSubmit (App.js:204)


And this is my code:



class Currency extends React.Component {
render() {
const p = this.props;
return (
<div className=currency>
{/*<span className=currencyText>&#x3C;Currency/&#x3E;</span>*/}
<div className=currencyInfo>
<div>{1 +p.base + = }</div>
<div>{p.data.rates}</div> {/*this is (App.js:402)*/}

</div>
</div>
);
}
}


Instead of that, If I code of Apps.js:402 like this:



<div>{p.data}</div>


and run the app, and check the console in chrome, the result for the line is empty.



The data that I mean is on the picture:



console



And this is the result of console prop p:



result



Any solution for this, so that I can retrieve the data rates from the currency?


More From » reactjs

 Answers
15

Ideally you want some way to manage loading and no-data states in your component, depending on what your api returns when there is no data - you might have to manage it differently but that is also a scenario you should cover. Your data seems to be coming from a prop called rates not data which is an object with multiple keys.



I am not certain of the structure of your code, but this iteration and checking for loading/no-data states might also be done in the parent component.



    class Currency extends React.Component {
render() {
const p = this.props;
const { rates = {} } = p;
const hasData = Object.keys(rates).length > 0;
return !p.loading ? (
<div className=currency>
<div className=currencyInfo>
{ hasData ?
<>
<div>{1 +p.base + = }</div>
{Object.entries(rates).map(([k, v]) => <div key={k}>{`${k}: ${v}`}</div>)}
</> : <p>No data available</p>
}
</div>
</div>
) : <Loader />
}
}


In a parent component you could do something like:



    class ParentComp extends React.Component {
public state = { loading: true, rates: {} };

componentDidMount() {
await this.fetchData(...); // could set loading to false on success
}

render() {
const { rates = {} } = this.state;
const hasData = Object.keys(rates).length > 0;
return (
!this.state.loading ?
hasData ?
Object.entries(rates).map(([k, v]) => <Currency key={k} name={k} value={v} ... />)
: <p>No data available</p>
: <Loader />
);
}
}


Then in your child component:



class Currency extends React.Component {
render() {
return (
<div className='currency'>
<div className='currencyInfo'>
<div>{`${this.props.name}: ${this.props.value}`}</div>
</div>
</div>
);
}
}


CREDITS:



Thanks to @Codebling for pointing out the unnecessary addition of v (value) in the key's


[#7280] Thursday, June 13, 2019, 5 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
dillionsalvadorg

Total Points: 288
Total Questions: 103
Total Answers: 75

Location: South Korea
Member since Sat, Oct 2, 2021
3 Years ago
dillionsalvadorg questions
Mon, Jun 14, 21, 00:00, 3 Years ago
Tue, Jul 7, 20, 00:00, 4 Years ago
Fri, Sep 21, 18, 00:00, 6 Years ago
;