Ajax call for each item in a map function
I have the following scenario where I need to make an ajax request to an endpoint for each item in the array while i map over it and display it on screen.
const items = [
{
id: 1,
name: "test"
},
{
id: 2,
name: "test2"
}
]
In my render() method:
render() {
return (
items.map((item) => {
<div>{item.name}</div>
// function that returns a promise
// the endpoint requires the item's id
this.apiCall(item.id).then((returnedValue) => {
return <div>{returnedValue}</div>
});
})
);
}
But running it throws this error:
Uncaught (in promise) Error: Minified React error #31; Objects are not valid as a React child (found: [object Promise]).
javascript reactjs
add a comment |
I have the following scenario where I need to make an ajax request to an endpoint for each item in the array while i map over it and display it on screen.
const items = [
{
id: 1,
name: "test"
},
{
id: 2,
name: "test2"
}
]
In my render() method:
render() {
return (
items.map((item) => {
<div>{item.name}</div>
// function that returns a promise
// the endpoint requires the item's id
this.apiCall(item.id).then((returnedValue) => {
return <div>{returnedValue}</div>
});
})
);
}
But running it throws this error:
Uncaught (in promise) Error: Minified React error #31; Objects are not valid as a React child (found: [object Promise]).
javascript reactjs
You need to return your JSX synchronously from the render method, so you are better of getting your API data incomponentDidMount
and setting it in the component state when the requests are done.
– Tholle
Nov 22 '18 at 23:04
@Tholle I tried your method but since i'm mapping overitems
and setting to state, state always gets set to the last item's call.
– ZeroDarkThirty
Nov 22 '18 at 23:19
Did any of the answers work for you? Consider accepting one of them if that's the case.
– Tholle
Nov 26 '18 at 23:11
add a comment |
I have the following scenario where I need to make an ajax request to an endpoint for each item in the array while i map over it and display it on screen.
const items = [
{
id: 1,
name: "test"
},
{
id: 2,
name: "test2"
}
]
In my render() method:
render() {
return (
items.map((item) => {
<div>{item.name}</div>
// function that returns a promise
// the endpoint requires the item's id
this.apiCall(item.id).then((returnedValue) => {
return <div>{returnedValue}</div>
});
})
);
}
But running it throws this error:
Uncaught (in promise) Error: Minified React error #31; Objects are not valid as a React child (found: [object Promise]).
javascript reactjs
I have the following scenario where I need to make an ajax request to an endpoint for each item in the array while i map over it and display it on screen.
const items = [
{
id: 1,
name: "test"
},
{
id: 2,
name: "test2"
}
]
In my render() method:
render() {
return (
items.map((item) => {
<div>{item.name}</div>
// function that returns a promise
// the endpoint requires the item's id
this.apiCall(item.id).then((returnedValue) => {
return <div>{returnedValue}</div>
});
})
);
}
But running it throws this error:
Uncaught (in promise) Error: Minified React error #31; Objects are not valid as a React child (found: [object Promise]).
javascript reactjs
javascript reactjs
asked Nov 22 '18 at 22:59
ZeroDarkThirtyZeroDarkThirty
63111128
63111128
You need to return your JSX synchronously from the render method, so you are better of getting your API data incomponentDidMount
and setting it in the component state when the requests are done.
– Tholle
Nov 22 '18 at 23:04
@Tholle I tried your method but since i'm mapping overitems
and setting to state, state always gets set to the last item's call.
– ZeroDarkThirty
Nov 22 '18 at 23:19
Did any of the answers work for you? Consider accepting one of them if that's the case.
– Tholle
Nov 26 '18 at 23:11
add a comment |
You need to return your JSX synchronously from the render method, so you are better of getting your API data incomponentDidMount
and setting it in the component state when the requests are done.
– Tholle
Nov 22 '18 at 23:04
@Tholle I tried your method but since i'm mapping overitems
and setting to state, state always gets set to the last item's call.
– ZeroDarkThirty
Nov 22 '18 at 23:19
Did any of the answers work for you? Consider accepting one of them if that's the case.
– Tholle
Nov 26 '18 at 23:11
You need to return your JSX synchronously from the render method, so you are better of getting your API data in
componentDidMount
and setting it in the component state when the requests are done.– Tholle
Nov 22 '18 at 23:04
You need to return your JSX synchronously from the render method, so you are better of getting your API data in
componentDidMount
and setting it in the component state when the requests are done.– Tholle
Nov 22 '18 at 23:04
@Tholle I tried your method but since i'm mapping over
items
and setting to state, state always gets set to the last item's call.– ZeroDarkThirty
Nov 22 '18 at 23:19
@Tholle I tried your method but since i'm mapping over
items
and setting to state, state always gets set to the last item's call.– ZeroDarkThirty
Nov 22 '18 at 23:19
Did any of the answers work for you? Consider accepting one of them if that's the case.
– Tholle
Nov 26 '18 at 23:11
Did any of the answers work for you? Consider accepting one of them if that's the case.
– Tholle
Nov 26 '18 at 23:11
add a comment |
3 Answers
3
active
oldest
votes
We can use Promise.all()
like that:
return (
Promise.all(items.map((item) => {
<div>{item.name}</div>
// function that returns a promise
// the endpoint requires the item's id
this.apiCall(item.id).then((returnedValue) => {
return <div>{returnedValue}</div>
});
})
);
add a comment |
You cannot perform an async operation in the render method, but you could encapsulate the Api call in a child component (which you would render instead), then you could handle the call inside the child component logic, something along these lines:
constructor(props) {
apiCall(props.id).then((value) => { this.setState({value}) });
this.state = {
value: ''
}
}
render() {
return (<div>{this.state.value}</div>);
}
add a comment |
You need to return your JSX synchronously from the render method, so you are better of getting your API data in componentDidMount
instead and setting it in the component state when the requests are done.
Example
class App extends React.Component {
state = { items: };
componentDidMount() {
const items = [
{
id: 1,
name: "test"
},
{
id: 2,
name: "test2"
}
];
Promise.all(
items.map(item =>
this.apiCall(item.id).then(returnedValue => {
item.returnedValue = returnedValue;
return item;
})
)
).then(items => {
this.setState({ items });
});
}
apiCall = id => {
return new Promise(resolve =>
setTimeout(() => resolve(Math.random()), 1000)
);
};
render() {
const { items } = this.state;
return (
<div>
{items.map(item => (
<div key={item.id}>
<div>{item.name}</div>
<div>{item.returnedValue}</div>
</div>
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438880%2fajax-call-for-each-item-in-a-map-function%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
We can use Promise.all()
like that:
return (
Promise.all(items.map((item) => {
<div>{item.name}</div>
// function that returns a promise
// the endpoint requires the item's id
this.apiCall(item.id).then((returnedValue) => {
return <div>{returnedValue}</div>
});
})
);
add a comment |
We can use Promise.all()
like that:
return (
Promise.all(items.map((item) => {
<div>{item.name}</div>
// function that returns a promise
// the endpoint requires the item's id
this.apiCall(item.id).then((returnedValue) => {
return <div>{returnedValue}</div>
});
})
);
add a comment |
We can use Promise.all()
like that:
return (
Promise.all(items.map((item) => {
<div>{item.name}</div>
// function that returns a promise
// the endpoint requires the item's id
this.apiCall(item.id).then((returnedValue) => {
return <div>{returnedValue}</div>
});
})
);
We can use Promise.all()
like that:
return (
Promise.all(items.map((item) => {
<div>{item.name}</div>
// function that returns a promise
// the endpoint requires the item's id
this.apiCall(item.id).then((returnedValue) => {
return <div>{returnedValue}</div>
});
})
);
answered Nov 22 '18 at 23:15
PoodePoode
39338
39338
add a comment |
add a comment |
You cannot perform an async operation in the render method, but you could encapsulate the Api call in a child component (which you would render instead), then you could handle the call inside the child component logic, something along these lines:
constructor(props) {
apiCall(props.id).then((value) => { this.setState({value}) });
this.state = {
value: ''
}
}
render() {
return (<div>{this.state.value}</div>);
}
add a comment |
You cannot perform an async operation in the render method, but you could encapsulate the Api call in a child component (which you would render instead), then you could handle the call inside the child component logic, something along these lines:
constructor(props) {
apiCall(props.id).then((value) => { this.setState({value}) });
this.state = {
value: ''
}
}
render() {
return (<div>{this.state.value}</div>);
}
add a comment |
You cannot perform an async operation in the render method, but you could encapsulate the Api call in a child component (which you would render instead), then you could handle the call inside the child component logic, something along these lines:
constructor(props) {
apiCall(props.id).then((value) => { this.setState({value}) });
this.state = {
value: ''
}
}
render() {
return (<div>{this.state.value}</div>);
}
You cannot perform an async operation in the render method, but you could encapsulate the Api call in a child component (which you would render instead), then you could handle the call inside the child component logic, something along these lines:
constructor(props) {
apiCall(props.id).then((value) => { this.setState({value}) });
this.state = {
value: ''
}
}
render() {
return (<div>{this.state.value}</div>);
}
answered Nov 22 '18 at 23:19
Code RangerCode Ranger
1847
1847
add a comment |
add a comment |
You need to return your JSX synchronously from the render method, so you are better of getting your API data in componentDidMount
instead and setting it in the component state when the requests are done.
Example
class App extends React.Component {
state = { items: };
componentDidMount() {
const items = [
{
id: 1,
name: "test"
},
{
id: 2,
name: "test2"
}
];
Promise.all(
items.map(item =>
this.apiCall(item.id).then(returnedValue => {
item.returnedValue = returnedValue;
return item;
})
)
).then(items => {
this.setState({ items });
});
}
apiCall = id => {
return new Promise(resolve =>
setTimeout(() => resolve(Math.random()), 1000)
);
};
render() {
const { items } = this.state;
return (
<div>
{items.map(item => (
<div key={item.id}>
<div>{item.name}</div>
<div>{item.returnedValue}</div>
</div>
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
add a comment |
You need to return your JSX synchronously from the render method, so you are better of getting your API data in componentDidMount
instead and setting it in the component state when the requests are done.
Example
class App extends React.Component {
state = { items: };
componentDidMount() {
const items = [
{
id: 1,
name: "test"
},
{
id: 2,
name: "test2"
}
];
Promise.all(
items.map(item =>
this.apiCall(item.id).then(returnedValue => {
item.returnedValue = returnedValue;
return item;
})
)
).then(items => {
this.setState({ items });
});
}
apiCall = id => {
return new Promise(resolve =>
setTimeout(() => resolve(Math.random()), 1000)
);
};
render() {
const { items } = this.state;
return (
<div>
{items.map(item => (
<div key={item.id}>
<div>{item.name}</div>
<div>{item.returnedValue}</div>
</div>
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
add a comment |
You need to return your JSX synchronously from the render method, so you are better of getting your API data in componentDidMount
instead and setting it in the component state when the requests are done.
Example
class App extends React.Component {
state = { items: };
componentDidMount() {
const items = [
{
id: 1,
name: "test"
},
{
id: 2,
name: "test2"
}
];
Promise.all(
items.map(item =>
this.apiCall(item.id).then(returnedValue => {
item.returnedValue = returnedValue;
return item;
})
)
).then(items => {
this.setState({ items });
});
}
apiCall = id => {
return new Promise(resolve =>
setTimeout(() => resolve(Math.random()), 1000)
);
};
render() {
const { items } = this.state;
return (
<div>
{items.map(item => (
<div key={item.id}>
<div>{item.name}</div>
<div>{item.returnedValue}</div>
</div>
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
You need to return your JSX synchronously from the render method, so you are better of getting your API data in componentDidMount
instead and setting it in the component state when the requests are done.
Example
class App extends React.Component {
state = { items: };
componentDidMount() {
const items = [
{
id: 1,
name: "test"
},
{
id: 2,
name: "test2"
}
];
Promise.all(
items.map(item =>
this.apiCall(item.id).then(returnedValue => {
item.returnedValue = returnedValue;
return item;
})
)
).then(items => {
this.setState({ items });
});
}
apiCall = id => {
return new Promise(resolve =>
setTimeout(() => resolve(Math.random()), 1000)
);
};
render() {
const { items } = this.state;
return (
<div>
{items.map(item => (
<div key={item.id}>
<div>{item.name}</div>
<div>{item.returnedValue}</div>
</div>
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
class App extends React.Component {
state = { items: };
componentDidMount() {
const items = [
{
id: 1,
name: "test"
},
{
id: 2,
name: "test2"
}
];
Promise.all(
items.map(item =>
this.apiCall(item.id).then(returnedValue => {
item.returnedValue = returnedValue;
return item;
})
)
).then(items => {
this.setState({ items });
});
}
apiCall = id => {
return new Promise(resolve =>
setTimeout(() => resolve(Math.random()), 1000)
);
};
render() {
const { items } = this.state;
return (
<div>
{items.map(item => (
<div key={item.id}>
<div>{item.name}</div>
<div>{item.returnedValue}</div>
</div>
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
class App extends React.Component {
state = { items: };
componentDidMount() {
const items = [
{
id: 1,
name: "test"
},
{
id: 2,
name: "test2"
}
];
Promise.all(
items.map(item =>
this.apiCall(item.id).then(returnedValue => {
item.returnedValue = returnedValue;
return item;
})
)
).then(items => {
this.setState({ items });
});
}
apiCall = id => {
return new Promise(resolve =>
setTimeout(() => resolve(Math.random()), 1000)
);
};
render() {
const { items } = this.state;
return (
<div>
{items.map(item => (
<div key={item.id}>
<div>{item.name}</div>
<div>{item.returnedValue}</div>
</div>
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
answered Nov 22 '18 at 23:33
TholleTholle
39.8k54366
39.8k54366
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438880%2fajax-call-for-each-item-in-a-map-function%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You need to return your JSX synchronously from the render method, so you are better of getting your API data in
componentDidMount
and setting it in the component state when the requests are done.– Tholle
Nov 22 '18 at 23:04
@Tholle I tried your method but since i'm mapping over
items
and setting to state, state always gets set to the last item's call.– ZeroDarkThirty
Nov 22 '18 at 23:19
Did any of the answers work for you? Consider accepting one of them if that's the case.
– Tholle
Nov 26 '18 at 23:11