GithubHelp home page GithubHelp logo

Empty `belongsTo` field in cache about data HOT 5 CLOSED

Jopie01 avatar Jopie01 commented on June 16, 2024
Empty `belongsTo` field in cache

from data.

Comments (5)

runspired avatar runspired commented on June 16, 2024 2
// Example of my converted payload
{
  "data": [
    {
      "type": "party.address",
      "id": 36,
      "attributes": {
        "id": 36
      },
      "relationships": {
        "subdivision": null
      }
    }
  ],
  "included": []
}

this is still not valid JSON:API, I'll fix it for you maybe that's the entire issue here 😅

// Example of my converted payload
{
  "data": [
    {
      "type": "party.address",
      "id": 36,
      "attributes": {
        "id": 36
      },
      "relationships": {
        "subdivision": { data: null } // this is the key change
      }
    }
  ],
  "included": []
}

from data.

Jopie01 avatar Jopie01 commented on June 16, 2024 1

that's the entire issue here
"subdivision": { data: null } // this is the key change

...... don't have to say anything anymore ..... That was the culprit.

from data.

Jopie01 avatar Jopie01 commented on June 16, 2024

Feels like a hack but when I convert the payload to JSON-API I get something like:

data: [{
  id: 45,
  type: 'party.address',
  attributes: { },
  relationships: {
    country: {
      id: 1,
      type: 'country',
      attributes: { }
    },
    subdivision: {
      id: null,
      type: 'country.subdivision'
    }
  }
}]

So when the relationships are handled in:

function setupRelationships(
storeWrapper: CacheStoreWrapper,
identifier: StableRecordIdentifier,
data: JsonApiResource
) {
// TODO @runspired iterating by definitions instead of by payload keys
// allows relationship payloads to be ignored silently if no relationship
// definition exists. Ensure there's a test for this and then consider
// moving this to an assertion. This check should possibly live in the graph.
const relationships = storeWrapper.getSchemaDefinitionService().relationshipsDefinitionFor(identifier);
const keys = Object.keys(relationships);
for (let i = 0; i < keys.length; i++) {
const relationshipName = keys[i];
const relationshipData = data.relationships![relationshipName];
if (!relationshipData) {
continue;
}
graphFor(storeWrapper).push({
op: 'updateRelationship',
record: identifier,
field: relationshipName,
value: relationshipData,
});
}
}

I added a small piece of code which checks if the id is null and if so, it adds a replaceRelatedRecord operation.

function setupRelationships(
  storeWrapper: CacheStoreWrapper,
  identifier: StableRecordIdentifier,
  data: JsonApiResource
) {
  // TODO @runspired iterating by definitions instead of by payload keys
  // allows relationship payloads to be ignored silently if no relationship
  // definition exists. Ensure there's a test for this and then consider
  // moving this to an assertion. This check should possibly live in the graph.
  const relationships = storeWrapper.getSchemaDefinitionService().relationshipsDefinitionFor(identifier);
  const keys = Object.keys(relationships);
  for (let i = 0; i < keys.length; i++) {
    const relationshipName = keys[i];
    const relationshipData = data.relationships![relationshipName];

    if (!relationshipData) {
      continue;
    }
    if (relationshipData.data.id === null) {
      graphFor(storeWrapper).push({
        op: 'replaceRelatedRecord',
        record: identifier,
        field: relationshipName,
        value: null
      });
      continue;
    }
    graphFor(storeWrapper).push({
      op: 'updateRelationship',
      record: identifier,
      field: relationshipName,
      value: relationshipData,
    });
  }
}

I know for sure you will come up with a much better and much more robust idea, but this works for me very reliably.

from data.

runspired avatar runspired commented on June 16, 2024
data: [{
  id: 45,
  type: 'party.address',
  attributes: { },
  relationships: {
    country: {
      id: 1,
      type: 'country',
      attributes: { }
    },
    subdivision: {
      id: null,
      type: 'country.subdivision'
    }
  }
}]

note this isn't the right JSON:API format and that's probably why this doesn't just work. The value for subdivision should just be null

There's a chance this is occurring because of using the wrong graph operation. If so I'd need more information, and would be happy to pair. I'd really like to get the graph package firmed up and made public soon 😅 (direct usage of it is not public yet but I'm hoping to get it there before 6.0). I would expect based on you extending the JSON:API Cache that you don't manually generate any graph operations for the "didCommit" following a save or "put" following a GET, only for "mutate". There's a chance it's the mutate operation going wrong.

from data.

Jopie01 avatar Jopie01 commented on June 16, 2024

The value for subdivision should just be null

When I do that, the data is ignored because of

if (!relationshipData) {

so no notification that the record is updated. The subdivision should still be in the relations object right?

... I'd need more information ...

What I really do is converting my JSONRPC payload into a JSONAPI payload and then I call super to let @ember-data do the rest. I pick it up again when I instantiate the record or getting the change notification.

// extending the JSON-API cache
class RPCCache extends Cache {

  // convert the JSON response into a JSONAPI response
  convertRPC(payload, model) {
    .....

    const result = {
      data: res,
      included: includes
    }
    return result;
  }

  put(document) {
    const method = document.request.data.method.split('.');
    const model = method.slice(1, method.length - 1).join('.');
    let content = document.content

    // convert the JSON-RPC payload from the backend to the JSON-API payload
    const payload = this.convertRPC(content, model);

    document.content = payload;
    return super.put(...arguments);
  }
}

// Example of my converted payload
{
  "data": [
    {
      "type": "party.address",
      "id": 36,
      "attributes": {
        "id": 36
      },
      "relationships": {
        "subdivision": null
      }
    }
  ],
  "included": []
}

There are no manual changes. The usecase I described is called an on_change. So when a field changes it will notify the backend that it has changed. Then the backend returns an object with data as response. That data is then fed into @ember-data which then notifies the change and my record magically updates the fields which were in the response. This works perfectly for all usecases. Sometimes 6 fields has to be updated which happens without any problem, but when a field should be emptied (backend returns a null for that field) that fails.

So in short:

  1. field is empty at the start
  2. field is filled based on another field which filtered out the records
  3. field must be emptied because that other field has changed which notified the backend who returned that the data of this field should be null. However this is never pushed into the cache and no notification.

from data.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.