Reputation: 1079
I have a reactJS application where I am trying to dynamically render some data that I read in with a fetch() promise. This is the code of my application:
import React from 'react';
import '../styles/app.css';
//think of react components as functions
class Testpage2 extends React.Component {
constructor(props) {
super(props);
this.state = {
numberOfRecords: 0,
productArray: [{
barcode: '',
name: ''
}]
};
}
componentDidMount() {
let currentComponent = this;
var recordCount = 0;
var tempData = [];
//Make use of the API not the web service.
let url = "http://wmjwwebapi-dev.us-west-2.elasticbeanstalk.com/api/getdata";
const options = { method: 'GET' };
fetch(url, options)
.then(function(response) {
return response.json();
})
.then(function(myJson) {
if (myJson == undefined)
{
console.log("fetch failed");
}
else
{
//inspect the data that the WebAPI returned
var return_code = myJson[0].return_code;
if (return_code == "Default Return code"){
recordCount = -2;
} else {
tempData = JSON.parse(myJson[0].return_string);
recordCount = tempData.barcode.length;
}
currentComponent.setState(
{
numberOfRecords: recordCount,
productArray: currentComponent.state.productArray.push(
{
name: tempData.name,
barcode: tempData.barcode
})
}
);
}
});
}
render() {
console.log(this.state.productArray);
return (
<div>
{ this.state.productArray.map((prod, index) => <li key={index}>{prod.barcode}</li>)}
</div>
)
}
}
export default Testpage2
and this is the error message that I am getting:
Uncaught (in promise) TypeError: this.state.productArray.map is not a function
at Testpage2.render (testpage2.js:67)
This is the result of the console.log() that I added in the render() function:
I'm not really sure what this error is telling me or how to go about debugging the issue.
Any help is greatly appreciated. Thank you.
Upvotes: 0
Views: 1110
Reputation: 6665
The return type of array.push is the new length of the array aka a number
So you set the state property productArray to a number and then try to call number.map which is not defined
How to fix?
push first and then use that array to set the state
const updatedArray = [...currentComponent.state.productArray]
updatedArray.push({ name: tempData.name, barcode: tempData.barcode })
currentComponent.setState({
numberOfRecords: recordCount,
productArray: updatedArray
}
Resources: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push
Upvotes: 1
Reputation: 8023
The JavaScript Array.push
method does not return the modified array, it returns the new length of the array, which is a number. Numbers in JavaScript do not have the map
method.
You need to do first create a clone of the productArray
, then push the new data, and finally set state:
const newProductArray = [...currentComponent.state.productArray]
newProductArray.push({
name: tempData.name,
barcode: tempData.barcode
})
currentComponent.setState(
{
numberOfRecords: recordCount,
productArray: newProductArray
}
)
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push
Upvotes: 0
Reputation: 15442
Array's push()
function returns integer, so you cannot call map()
function on it. Try to change your function to:
currentComponent.setState({
numberOfRecords: recordCount,
productArray: [...currentComponent.state.productArray, {
name: tempData.name,
barcode: tempData.barcode
}]
})
Upvotes: 0
Reputation: 1723
According to MDN:
The push() method adds one or more elements to the end of an array and returns the new length of the array.
It appears that your code expects that Array.push()
will return the modified array itself:
productArray: currentComponent.state.productArray.push(...
To prevent the state corruption you should do construct the new array separately, before invoking setState()
.
Upvotes: 0