Breeze / breeze-client

Breeze for JavaScript clients
MIT License
38 stars 16 forks source link

Breeze client issue with nested arrays #60

Open JulienBerrier opened 3 years ago

JulienBerrier commented 3 years ago

Hello Breeze team.

I encountered an issue with nested arrays and I wanted to share it with you because I think this is a bug in Breeze-client. Since I'm not a expert on the subject, maybe I did something wrong. In any case, this topic will clarify it and maybe help others that are in the same situation as me.

Let's assume we have this data object :

{
    "_id": "614d090791c2221e5d09022d",
    "name": "Test",
    "files": [
        {
            "name": "Test",
            "filepath": "test"
        },
        {
            "name": "Test 2",
            "filepath": "test2"
        },
        {
            "name": "Test 3",
            "filepath": "test3"
        }
    ]
}

In the metadata, we have a complex object to match the nested objects in the array :

// Only showing configuration for nested array
{
  "name":"files",
  "complexTypeName":"fileData",
  "isScalar": false,
},
{
  "shortName": "fileData",
  "isComplexType": true,
  "dataProperties": [
    {
      "name":"name",
      "dataType":"String"
    },
    {
      "name":"filepath",
      "dataType":"String"
    }
  ]
}

Even if the metadata documentation is not mentioning the use of scalar, I found a topic on stack overflow that was stating this is the way to proceed for nested arrays, even if the topic is a little old : https://stackoverflow.com/questions/22055013/breeze-js-metadata-by-hand-for-an-array-type

If I use nested objects and put isScalar: true, this is working fine. But when I want to have a nested array with multiples object values, I encountered a issue when calling the entity manager method createEntity() : the object created by the entity manager from the metadata and the raw json was incomplete. Array was empty. We lost silently the array values during the call.

I've traced the issue witch seems to be located in the file breeze-client\src\complex-array.ts. Inside this file, we have two methods that are called during the conversion process : getGoodAdds() and processAdds().

In getGoodAdds we have a condition that is removing our values within the filtering method : a.complexAspect.parent !== complexArray.parent. The problem is, in this use case, this condition seems false. It's normal that the parent is already there in case of an nested array : sub elements have all the same parent.

To made it work, I changed sightly theses two methods to not filter the results and ignore if the parent is already declared :

function getGoodAdds(complexArray: ComplexArray, adds: ComplexObject[]) {
  return adds;
}

function processAdds(complexArray: ComplexArray, adds: ComplexObject[]) {
  adds.forEach(function (a) {
    setAspect(a, complexArray);
  });
}

After the changes, it works : I have my nested values as intended. But since I don't have the big picture, I don't know what is the impacts for others features to have removed the original conditions. I guess there were here to serve a purpose, but I'm not an expert on Breeze source code so it's hard for me to tell.

So, here's the main purpose of this topic : did I do something wrong in configuration or do Breeze-client has a bug with nested arrays ?

Thanks for you feedback !

steveschmitt commented 3 years ago

I think this is one for @jtraband .