reactjs - Redux Observable, React, componentDidMount fetch from API cannot get properties from objects -


import { fetchposts  } '../actions'; import react, {component} 'react'; import {bindactioncreators, dispatch} 'redux'; import {connect} 'react-redux'; import proptypes  'prop-types'; import map 'lodash/fp/map'; import flatten 'lodash/fp/flatten'; import sortby 'lodash/fp/sortby'; import compose 'lodash/fp/compose'; import take 'lodash/fp/take'; import _ 'lodash';   class postsindex extends component {  state = {     posts: [] };      componentdidmount() {          this.props.fetchposts();       }      displayposts () {         //console.log(post) works, console.log(post.title) returns undefined.         return  _.map(this.props.posts, (post)=>{debugger;console.log(post.title);});     }      render() {         if(this.props.posts.length === 0) {             return (<div>loading...</div>);         }         return (<ul>{this.displayposts()}</ul>);     } }  function mapstatetoprops(state) {     return {         posts: (state.posts) ? state.posts : []     }; }  function mapdispatchtoprops (dispatch) {     return  bindactioncreators({fetchposts: fetchposts}, dispatch);    }  export default connect(mapstatetoprops, mapdispatchtoprops)(postsindex); 

i can console.log(post) in

    displayposts () {         //console.log(post) works, console.log(post.title) returns undefined.         return  _.map(this.props.posts, (post)=>{debugger;console.log(post.title);});     } 

but if try console.log(post.title) undefined.

likewise if try like:

    displayposts () {         //console.log(post) works, console.log(post.title) returns undefined.         return  _.map(this.props.posts, (post)=>{return <div>post.title</div>;});     } 

i nothing back.

down here can see result of console.log(). former comes epic latter 1 component.

console logs

here there's link repo did open: https://github.com/deviad/redux-router-playground

the problem in reducer (found linked repo):

export default function postsreducer(state=[], action) {     switch (action.type) {         case actiontypes.fetch_posts_fullfilled:             // problem:             return [                 ...state,                 action.payload             ];          default:             return state;     } }; 

action.payload array, place inside array, array of arrays. when map on this.props.posts 1 result, actual array of posts. when logging, didn't notice.

// problem: return [     ...state,     action.payload ]; 

instead, could return array as-is:

return action.payload; 

while above solution imo acceptable (and let's honest, shipping code #1 priority), still not idiomatic way use redux. instead, think of redux database. how store (aka normalize) these in database? if answered "indexed id" you're right!

so redux state might this:

{     posts: {         '123': {             id: '123',             title: 'first title'         },         '456': {             id: '456',             title: 'second title'         }     } } 

here's 1 way might that:

export default function postsreducer(state = {}, action) {     switch (action.type) {         case actiontypes.fetch_posts_fullfilled:             return action.payload.reduce((acc, post) => {                 acc[post.id] = post;                 return acc;             }, { ...state });             // use object.assign if object-spread             // syntax isn't supported          default:             return state;     } }; 

because variations of common, many times nested, choose use normalizr library instead:

import { normalize, schema } 'normalizr';  const postschema = new schema.entity('posts');  export default function postsreducer(state = {}, action) {     switch (action.type) {         case actiontypes.fetch_posts_fullfilled:             // use object.assign if object-spread             // syntax isn't supported             return {                 ...state,                 ...normalize(action.payload, [postschema]).entities.posts             }; // etc 

since in case need them array of posts in ui container, has utilities denormalizing well, or can object.values if supported:

function mapstatetoprops(state) {     return {         posts: object.values(state.posts)     }; } 

the normalize() call returns array of ids might find useful store in redux somewhere, or use object.keys(state.posts) on-demand when need it--this because prevents synchronization issues, it's not practical perf reasons if number of items massive. that's issue worry when happens.

you may wondering why on earth go trouble if we're going denormalize again; full answer long winded, short gist consistency, ease of future state updates, , quick "post id" lookup later views. major part of makes redux great, otherwise becomes time-travelling glorified getter/setter, not worth boilerplate.

this discussed in normalizing state shape section of redux docs.


Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -