aribouius/jsonapi-react

Resource Meta Information Not Included

aidandamerell opened this issue · 4 comments

When a single resource contains a meta field, this is not accessible.

{
  "data": {
    "id": "SOME ID",
    "type": "A TYPE",
    "links": {
      "self": "A LINK"
    },
    "attributes": {
      "name": "A Name",
      "address": "an Address",
      "createdAt": "2020-06-22T20:28:44.245Z",
      "archived": false
    },
    "relationships": {
      "thing": {
        "links": {
          "self": "A LINK",
          "related": "A LINK"
        }
      },
      "anotherthing": {
        "links": {
          "self": "A LINK",
          "related": "A LINK"
        }
      }
    },
    "meta": {
      "a": "b"
    }
  }
}
const { data, meta, error, isLoading } = useQuery(uuid && ['type', uuid, { include: 'thing' }])

console.log(meta) => undefined

console.log(data && data.meta) => undefined

Have I missed something?

This is what is providing the data: https://jsonapi-resources.com/v0.9/guide/resources.html#Resource-Meta

hi @aidandamerell,

This library doesn't currently assign resource level fields other than attributes (e.g. meta, links, etc). It's something I'd love to find a good solution for, but the primary problem is just where to put it.

I.e. assigning a meta or links field onto the attributes object is possible, but it introduces the risk of field collision, if your model actually has fields with those names (meta in particular is a fairly common field to have on models).

That being said, you are able to add a custom attribute resolver to append such values via the schema config. While custom resolvers are typically intended for existing attributes, you are allowed to define a an arbitrary field.

The resolver receives 3 arguments:

  • The attribute value (if it exists)
  • The attributes object
  • The raw data object, that contains id, type, attributes, links, etc.
const schema = {
  todos: {
    type: 'todos',
    fields: {
      my_custom_field: {
        resolve: (value, attrs, data) => {
          return data.links.self
        }
      }
    },
}

Hey @aribouius, would it not be possible to address this by renaming the meta key if there is a collision?

@aidandamerell sure its possible, but I have two reservations about implementing that right now:

  1. I'd prefer a consistent method of accessing the meta, having it be either this or that is confusing.
  2. It would be a breaking change.

What do you think about using a _ prefix for not attribute data? E.g. { _meta: {}, _links: {} }

Well that’s a much better idea and would certainly extent the library!