UzumakiDev
UzumakiDev

Reputation: 1276

Merging nested ImmutableJS records doesn't gives me undefined, nested entities

I'm new to the immutableJS library and my javascript could be a lot better than it is.

I have a react project that's using redux and I've read that best practise is to make you store immutable, so knowing that I've looked up some methods of doing that and decided to use ImmutableJS, specifically using their Record class.

But it seems I've gotten lost along the way.

Here's my setup:

I created my Records here.

const Form = Record({
  id: 0,
  status: "",
  name: "default",
  action: "",
  method: "",
  submit: "",
  fields: new Field()
});

const Entity = Record({
  id: undefined,
  status: "",
  messages: new Message(),
  redirectTo: "",
  entityType: "",
  isFetching: false,
  lang: "",
  title: "",
  charset: "",
  viewport: "",
  description: "",
  keywords: "",
  forms: new Form(),
  socialLoginText: "",
  forgotPasswordLinkText: "",
  registerLinkText: ""
});

As you can see I've created other Records and added the main Entity record.

Now after importing my Entity I'm setting up my initialState, here:

const entity = new Entity()

const initialState = OrderedMap().mergeDeep(entity)

If I'm correct, this should make my initialState the complete immutable structure I want my state to be in, also giving it access to Records default values.

Next I do a Fetch action and normalize the response which gives me this output:

{fields: {…}, forms: {…}, messages: {…}, entity: {…}}
entity:{0: {…}}
fields:{0: {…}, 1: {…}, 2: {…}}
forms:{0: {…}, 1: {…}}
messages:{0: {…}, 1: {…}, 3: {…}}

This seems right to me but I could be wrong, there is no [results] field but I assume its because my API endpoint provides a single item of data with nested entities like this.

{
id: 0,
status: "success",
redirectTo: "",
messages: [
    {
       id: 0,
       type: "primary",
       icon: "https://s3.amazonaws.com/uifaces/faces/twitter/ripplemdk/128.jpg",
       title: "error nam enim",
       message: "Illum minus velit voluptatum voluptate.",
       dismissable: true,
       dismissAfter: 0,
       redirect: false,
       redirectTo: "",
       redirectAfter: 0
     } ...

Assuming I haven't gone wrong earlier... this is where I think I'm going wrong any Immutable Records/Maps are getting messed up.

I'm calling this function to use Immutable's fromJS to convert my Object into a Maps and Lists.

mergeEntities(state, fromJS(action.payload.entities)

I then merge my state OrderedMap with my new Map data, calling a couple helper methods along the way.

const mergeEntities = (state, payload) => {
  return state.merge(
    entity.setFetching(false),
    entity.setStatus('success'),
    payload.map(
      (id) => new Entity(id)
    )
  )
}

I iterate over the map creating instances of my Entity Record, this is where I think I'm going wrong. Everything works fine at the top level, I can call:

state.entity.get('forms')

And it returns me the form Map, then things get a bit weird, to get a specific form I then have to use:

state.entity.get('forms')._map.get('0')

Which returns a form Map, then this is where I'm stuck, using:

state.entity.get('forms')._map.get('0').get('fields')

Returns undefined, the console log of ... ._map.get('0') looks like this:

enter image description here

There's probably multiple places I'm going wrong, some help and guidance would be much appreciated.

Upvotes: 0

Views: 573

Answers (1)

UzumakiDev
UzumakiDev

Reputation: 1276

I was basing my Records on the API state, not the Normlized state schema I created, and I was using the top most Record to create all of the nested maps structure.

Upvotes: 0

Related Questions