mrichar1 / jsonapi-vuex

Use a JSONAPI api with a Vuex store, with data restructuring/normalization.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Are associated keys misnamed?

geoidesic opened this issue · comments

So I have a model which has a m21 association defined by a key named entity_type_id. However in my jv model this turns up as a property named entity-type, which makes it difficult to match expected key with actual key.

What's up with that?

E.g. where it's a problem would be I want to perform a filtered search based on a number of fields. To do so I have to cycle through the fields and compare them with the keys in the model. If my field has a different name from the _jv model then that's not going to work.

jsonapi-vuex doesn't do any renaming or modification of key names - it only does some rearranging to the normalised structure.

Can you post examples of the jsonapi data returned by the API, and the resulting normalised data? (a 'get' action with preserveJSON: true in the module config should be enough).

Ok I've looked into this and I can see that the renaming is happening on the back-end and it's required by the JSONAPI spec because said spec doesn't allow _id for some reason. Which is fine but then then I'm still not sure how to work with it on the front-end.

Here's the normalised (? not sure if it is as I haven't quite grokked what you mean by normalised in this context) data:

{
  "_jv": {},
  "organisations": {
    "2": {
      "_jv": {
        "type": "organisations",
        "id": "2",
        "relationships": {
          "role": {
            "links": { "self": "/api/roles/view/3" },
            "data": { "type": "roles", "id": "3" }
          },
          "entity-type": {
            "links": { "self": "/api/entity-types/view/2" },
            "data": { "type": "entity-types", "id": "2" }
          }
        },
        "links": { "self": "/api/organisations/2" },
        "isRel": {
          "_custom": {
            "type": "function",
            "display": "<span>ƒ</span> isRel(name)"
          }
        },
        "isAttr": {
          "_custom": {
            "type": "function",
            "display": "<span>ƒ</span> isAttr(name)"
          }
        }
      },
      "name": "Arc Digital Limited",
      "email": null,
      "phone": null,
      "address1": null,
      "address2": null,
      "town": null,
      "country": null,
      "county": null,
      "postcode": null,
      "created": "2020-05-03T14:39:45+00:00",
      "modified": "2020-05-03T14:39:45+00:00"
    },
  }
}

Here's the JSONAPI return:

{
    "meta": {
        "record_count": 1,
        "page_count": 1,
        "page_limit": null
    },
    "links": {
        "self": "/api/organisations?page=1",
        "first": "/api/organisations?page=1",
        "last": "/api/organisations?page=1"
    },
    "data": [
        {
            "type": "organisations",
            "id": "2",
            "attributes": {
                "name": "Arc Digital Limited",
                "email": null,
                "phone": null,
                "address1": null,
                "address2": null,
                "town": null,
                "country": null,
                "county": null,
                "postcode": null,
                "created": "2020-05-03T14:39:45+00:00",
                "modified": "2020-05-03T14:39:45+00:00"
            },
            "relationships": {
                "role": {
                    "links": {
                        "self": "/api/roles/view/3"
                    },
                    "data": {
                        "type": "roles",
                        "id": "3"
                    }
                },
                "entity-type": {
                    "links": {
                        "self": "/api/entity-types/view/2"
                    },
                    "data": {
                        "type": "entity-types",
                        "id": "2"
                    }
                }
            },
            "links": {
                "self": "/api/organisations/2"
            }
        }
    ]
}

So if I was creating a form for adding an organisation and I wanted to include a select element to choose the entity-type by id, it's not clear to me what the model name for that value should be nor how I would then PATCH that onto the organisation after it has been added.

Perhaps you could add a PATCH for association example to the README?

Looking at this it appears that there is a relationship set up on the API with the relationship name entity-type. Behind the scenes, this is linked in the DB by the entity_type_id foreign key, but this will never show up as foreign keys are forbidden from appearing as attributes by the jsonapi spec (which makes sense, since this is what relationships are for).

Of course the jsonapi-vuex version of the data has the ability to include relationships as if they were attributes, which is why you see an entity-type attribute if recurseRelationships is enabled. Note however this isn't a real value, and is just a 'pointer' of sorts to the related item elsewhere in the store.

There are 2 ways to change a relationship for an object in the spec, though only one is currently supported: https://jsonapi.org/format/#crud-updating-resource-relationships (The other one is scheduled to come with #88)

So you have to change the value in the relationships section directly, e.g.:

myData._jv.relationships.entity-type.data.id = 3

So you need to have your select element's values be the id's of the potential entity-types.

Note: if cleanPatch config option is enabled, then you need to explicitly tell it to preserve any of links, meta or relationships if you are modifying them, by setting the module config to have e.g.:

cleanPatch: true,
cleanPatchProps: ['relationships']
commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.