nazirov91 / ra-strapi-rest

React Admin data provider for Strapi.js
125 stars 40 forks source link

Handle Strapi Components Show And Update #29

Closed AsharDweedar closed 1 year ago

AsharDweedar commented 4 years ago

When A schema from strapi includes a 'component' field; It will be replaced with IDs hence the 'show' and 'Edit' will fail to show proper data. (since components do not have 'crud's in strapi)

I had To Do Something Like This:

    const replaceRefObjectsWithIds = json => {
        Object.keys(json).forEach(key => {
        const fd = json[key]; // field data
        const referenceKeys = [];
        if (fd && (fd.id || fd._id) && !fd.mime) {
                json[key] = fd.id || fd._id;
        } else if (Array.isArray(fd) && fd.length > 0 && !fd[0].mime) {
                fd.map(item => referenceKeys.push(item.id || item._id));
                if(key != "KEY_IN_DOCUMENT_REFERS_TO_AN_ARRAY_OF_COMPONENTS") { // HERE -----------
                    json[key] = referenceKeys;
                }
        }
    });

To Avoid component values being replaced with IDs

nazirov91 commented 4 years ago

Do you have any suggestions on how to account for this type of situations without breaking other scenarios (i.e. image upload) ? A pull request will be appreciated. Thank you!

AsharDweedar commented 4 years ago

Actually no I don't, the only solution I could do is this if condition; other solution might be adding a custom endpoint on strapi to get the component's document.

I wished you knew a better way than mine; nevertheless; not sure if you would consider the approach of receiving a list of "KEY_IN_DOCUMENT_REFERS_TO_AN_ARRAY_OF_COMPONENTS" like the one I used when initialing the data provider alongside the API link; that I can do a pull request for.. feels like a silly way to go but that can only other way be handled this way; or by customizing strapi to not send id in the component's object or sending "isComponent" key with it to use it as a reference

ranaharoon3222 commented 3 years ago

where to add above code?

AsharDweedar commented 3 years ago

@ranaharoon3222 Fnd the function replaceRefObjectsWithIds, this is the one responsible for replacing the json[key] with either the object's ID or array of IDs if the value was an array of components; there you should add your condition to not replace the value in the document if it was a component.

for me my code looked like this:

  // Replace reference objects with reference object IDs
  const replaceRefObjectsWithIds = (json) => {
    Object.keys(json).forEach((key) => {
      const fd = json[key]; // field data
      const referenceKeys = [];
      if (fd && (fd.id || fd._id) && !fd.mime) {
        if (!isComponentsKeys(key)) {
          json[key] = fd.id || fd._id;
        } else {
          delete fd.id;
        }
      } else if (Array.isArray(fd) && fd.length > 0 && !fd[0].mime) {
        fd.map((item) => referenceKeys.push(item.id || item._id));
        if (!isComponentsKeys(key)) {
          json[key] = referenceKeys;
        }
      }
    });
    return json;
  };

isComponentsKeys is a function I defined to decide whether this is a component object or a populated object id for a document, you can add your logic there.

ranaharoon3222 commented 3 years ago

can you please share isComponentsKeys function please

AsharDweedar commented 3 years ago

mine is as simple as:

const componentsKeys = [
  "key1",
  "key2"
];

function isComponentsKeys(k) {
  return componentsKeys.indexOf(k) !== -1;
}

where I have documents like:

[
  {
    "id": "---",
    "name:": "something",
    "key1": {
      "id": "component id",
      "option": "some value"
    },
    "key2": [
      {
        "id": "component 2 id",
        "option": "some value"
      },
      {
        "id": "component 3 id",
        "option": "some other value"
      },
    ]
  }
]

it's stupidly hard coded so you might have a better way.

ranaharoon3222 commented 3 years ago

thank you soo much you are great!!!!!

nazirov91 commented 1 year ago

Hi!

Please see the readme file. I have updated the package to make it work with Strapi V4. Please open a new issue if the problem persists.

Thanks!