Closed MartinKutz closed 4 years ago
Hi @MartinKutz ,
You are right that it is not correct compare className with Resource string.
But I think you problem is not in code ResourceHelper.className(resource[key]).find((className) => className === 'Resource')
.
If resource[key]
is MyBaseResource
it should has _links
object because it extend Resource
class and condition will be passed by the second part || resource[key]._links
.
Can you provide more information about you code? I will try to reproduce this behavior and say what is the problem.
Hi @lagoshny,
Thank you for your very fast reply! :-)
You're right, the Resource
is not the problem.
I debugged a bit deeper in the code, and I hope I have found the problem.
First, here is a simplified example after entering this method:
const payload = ResourceHelper.resolveRelations(entity);
entity (before and after entering the method):
{
"name":"MySampleProduct",
"availableLanguages":[
{
"name":"en-US",
"key":"en-US",
"_links":{
"self":{
"href":"http://localhost:4200/rke/api/languages/7"
},
"language":{
"href":"http://localhost:4200/rke/api/languages/7"
},
"i18n":{
"href":"http://localhost:4200/rke/api/workspaces/1/i18n?language=en-US"
},
"workspace":{
"href":"http://localhost:4200/rke/api/languages/7/workspace"
}
}
},
{
"name":"en",
"key":"en",
"_links":{
"self":{
"href":"http://localhost:4200/rke/api/languages/8"
},
"language":{
"href":"http://localhost:4200/rke/api/languages/8"
},
"i18n":{
"href":"http://localhost:4200/rke/api/workspaces/1/i18n?language=en"
},
"workspace":{
"href":"http://localhost:4200/rke/api/languages/8/workspace"
}
}
}
],
"defaultLanguage":"http://localhost:4200/rke/api/languages/8",
"_links":{
"self":{
"href":"http://localhost:4200/rke/api/sampleProducts/5911"
},
"sampleProduct":{
"href":"http://localhost:4200/rke/api/sampleProducts/5911"
},
"validate":{
"href":"http://localhost:4200/rke/api/sampleProducts/validate?id=5911"
},
"save":{
"href":"http://localhost:4200/rke/api/sampleProducts/5911"
},
"delete":{
"href":"http://localhost:4200/rke/api/sampleProducts/5911"
},
"defaultLanguage":{
"href":"http://localhost:4200/rke/api/sampleProducts/5911/defaultLanguage"
},
"availableLanguages":{
"href":"http://localhost:4200/rke/api/sampleProducts/5911/availableLanguages"
}
}
}
payload return value:
{
"name":"MySampleProduct",
"availableLanguages":[
{
"name":"en-US",
"key":"en-US",
"_links":{
"self":{
"href":"http://localhost:4200/rke/api/languages/7"
},
"language":{
"href":"http://localhost:4200/rke/api/languages/7"
},
"i18n":{
"href":"http://localhost:4200/rke/api/workspaces/1/i18n?language=en-US"
},
"workspace":{
"href":"http://localhost:4200/rke/api/languages/7/workspace"
}
}
},
{
"name":"en",
"key":"en",
"_links":{
"self":{
"href":"http://localhost:4200/rke/api/languages/8"
},
"language":{
"href":"http://localhost:4200/rke/api/languages/8"
},
"i18n":{
"href":"http://localhost:4200/rke/api/workspaces/1/i18n?language=en"
},
"workspace":{
"href":"http://localhost:4200/rke/api/languages/8/workspace"
}
}
}
],
"defaultLanguage":"http://localhost:4200/rke/api/languages/8",
"_links":{
"self":{
"href":"http://localhost:4200/rke/api/sampleProducts/5911"
},
"sampleProduct":{
"href":"http://localhost:4200/rke/api/sampleProducts/5911"
},
"validate":{
"href":"http://localhost:4200/rke/api/sampleProducts/validate?id=5911"
},
"save":{
"href":"http://localhost:4200/rke/api/sampleProducts/5911"
},
"delete":{
"href":"http://localhost:4200/rke/api/sampleProducts/5911"
},
"defaultLanguage":{
"href":"http://localhost:4200/rke/api/sampleProducts/5911/defaultLanguage"
},
"availableLanguages":{
"href":"http://localhost:4200/rke/api/sampleProducts/5911/availableLanguages"
}
}
}
I think the problem is in the array part of the code. If the resource[key]
is an array, it enters the part
result[key].push(this.resolveRelations(element));
foreach element in the array.
So in the above example for defaultLanguages
, the resolveRelations
will be called with:
{
"name":"en-US",
"key":"en-US",
"_links":{
"self":{
"href":"http://localhost:4200/rke/api/languages/7"
},
"language":{
"href":"http://localhost:4200/rke/api/languages/7"
},
"i18n":{
"href":"http://localhost:4200/rke/api/workspaces/1/i18n?language=en-US"
},
"workspace":{
"href":"http://localhost:4200/rke/api/languages/7/workspace"
}
}
}
I think here begins the problem. Because, now every key of the object is iterated, e.g. name
, key
, _links
.
So resource[key]._links
will never be true.
I think with this change it should work: Instead of
result[key].push(this.resolveRelations(element));
use
result[key].push(this.resolveArrayEntity(element));
and resolveArrayEntity
is:
static resolveArrayEntity(resource) {
if (resource._links) {
return resource._links.self.href;
}
return resolveRelations(resource);
}
@MartinKutz , thanks for your explanation, but I can't still reproduce it.
I pushed a new branch issue-26 where I created the resource-helper.spec.ts
to simulate your above example. But test passed successfully.
Can you look at this test and say what need to change to reproduce your behavior?
For run the test you need switch to the issue-26
branch and type in terminal the ng test
command.
@lagoshny , thanks again for the fast reply and creating the unit test :-)
Oh no, it's fixed with the newest version. I'm sorry that you had work with it :-( It was fixed with commit 33694c76e449133a5da2452dd4f9d9358819937e on 9th April.
My last update was end of march. With the newest version it's now working - thanks for your help!
@MartinKutz, ok, no problem)
If the application needs it's own abstract implementation of Resource, e.g. 'MyBaseResource', the replacement of objects to links is not working.
I debugged into the library and found the function where the Resources gets replaced by the links. In the function "static resolveRelations(resource)" the problem is in this code snippet:
It checks via string to 'Resource'. If the snippet/function would you the instanceof function, the implementation should work also for Resource derived base classes.