How to map every array object in (Laravel - ReactJS)
How to map every array object in (Laravel - ReactJS)
I new here in React Js With Laravel Php Framework.
The Problem:
Is it possible to get every array object to my API and fetch it in every section.because i got an error in my console that says
Uncaught TypeError: this.state.missions.map is not a function. I don't know what the problem is but the main goal is to get every object and the loop must be in specific div section in the views
Ex. If i already get the array object of mission and store
<div className="mission">
the object of mission must be here.
</div>
<div className="store">
the object of store must be here.
</div>
and other object. etc
My Controller:
public function index()
$content_mission = DB::table('content_structure')
->where('content_pages','=','Home')
->where('content_section','=','Mission-Vision')
->where('status','=','Active')
->orderBy('content_id','Desc')
->limit(1)
->get();
$content_store = DB::table('content_structure')
->leftJoin('content_upload_assets','content_structure.content_id','=','content_upload_assets.cid')
->where('content_pages','=','Home')
->where('content_section','=','Store')
->where('status','=','Active')
->orderBy('content_id','Desc')
->limit(1)
->get();
return response()->json(
array(
'mission'=>$content_mission,
'store'=>$content_store)
);
My Components:
export default class Content extends Component
constructor()
super();
this.state =
missions: ,
store: ,
componentWillMount()
axios.get('/api/contents').then(response =>
this.setState(
missions: response.data
);
).catch(error =>
console.log(error);
)
render()
return (
<div>
// this div is for mission
<div className="mission-section">
<h1></h1>
<p></p>
<div className="container">
this.state.missions.map(mission => <li>mission.content</li>)
</div>
</div>
//this div is for store
<div className="Store"></div>
</div>
)
if(document.getElementById('app'))
ReactDOM.render(<Content/>, document.getElementById('app'));
this.state.missions
how to solved it?
– DevGe
Sep 5 '18 at 6:16
It seems that you're returning an object from your API response. Can you try
response.data.missions
?– Alserda
Sep 5 '18 at 6:45
response.data.missions
You are fetching that state
missions
property before Api call has been completed. Also I am not sure response.data is an array. Main cause for Error : response.data
cannot be typeof array.– Meet Zaveri
Sep 5 '18 at 6:49
missions
response.data
@Alserda same error
– DevGe
Sep 5 '18 at 6:51
2 Answers
2
this error is because you are fetching data async but by the time component getting rendered the data is not ready yet so you can have a flag that shows data is fetching and when the flag is flase or true as you want. you can render your data by a && operator in return like this :
this.state.flag && this.state.missions.map(mission => <li>mission.content</li>)
or you can easily say render it when there was any data
&& this.state.missions this.state.missions.map(mission => <li>mission.content</li>)
Question: is it okay to use multiple componentWillMount()
– DevGe
Sep 5 '18 at 7:34
as a matter of fact you should not use componentwillMount anymore you can read about it here stackoverflow.com/questions/41612200/…
– ehsan.jso
Sep 5 '18 at 7:40
From json_encode php manual:
Associative array always output as object:
"foo":"bar","baz":"long"
Controller
return response()->json(
array(
'mission'=>$content_mission,
'store'=>$content_store
)
);
returns json object with mission
and store
properties. Check this on browser network tab.
mission
store
Rename componentWillMount
into componentDidMount
and use proper data references, sth like:
componentWillMount
componentDidMount
componentDidMount()
axios.get('/api/contents').then(response =>
this.setState(
missions: response.data.missions,
store: response.data.store
);
).catch(error =>
console.log(error);
)
Later in render it's safe to use
this.state.missions.map(mission => <li>mission.content</li>)
as initially this.state.missions
is an empty array and will be updated with loaded array - earlier value was updated with an object.
this.state.missions
This:
this.state.missions && this.state.missions.map(mission => <li>mission.content</li>)
would be good hint for deeper references (f.e. this.state.missions.tasks
) unavailable in initial state. In this case it should be rather
this.state.missions.tasks
(this.state.missions.length>0) && this.state.missions.map(mission => <li>mission.content</li>)
This condition can be used to replace entire view:
render() {
if (!this.state.missions.length) return <Loading />
return (
// title
// missions map
// store map
avoiding conditions in many places.
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
The error you indicated clearly states that
this.state.missions
is not an array or typeof array.– Meet Zaveri
Sep 5 '18 at 6:15