Closed Melzar closed 7 years ago
Hello.
I think it's related to the JSON.stringify
.
The provided json can be stringify becouse it has circular attributes on itself.
Something like that
let d = {
data: 'Hello'
};
d.me = d;
JSON.stringify(d); // that will throw and error Converting circular structure to JSON.
So please check your json object.
Thank you for your quick response.
I've performed deeper 'inception' into source code and the issue was related to partially to new $resource property but the main reason was related to dependency injection and injecting router which caused issue which I've described.
Thanks again fro your help.
Sorry... I have read the issue quickly, I'm on AngularCamp now. I will check deeper the problem a bit latter. Could you please your resource class here or make some plunker. Thank you!
Not a problem. I've solve this issue but as a hint - If you define a constructor with dependency injection in your service and provided dependency will be router or http service then you will face issue which I've described.
I've solved this issue just by removing constructor ( actually I could do this in my case but for other cases it might not work as expected ).
Making things short :
Inject in constructor for example http: Http. Then it will be available in your $resource property. Then just follow my post above to reproduce this issue.
Example service
@Injectable()
@ResourceParams({
url: 'my url'
})
export class MyService extends ResourceCRUD<any, any, any> {
@ResourceAction({
path: '/item/{!id}',
})
getItem: ResourceMethod<{
id: any;
}, Item[]>;
constructor(private router: Router, private http: Http ){
super(http);
}
}
I've got the same problem.
I use ngx-resource like this:
@Injectable()
@ResourceParams({
withCredentials: true,
url: BASE_URL + '/v2',
})
export class RestClient extends Resource {
constructor(http: Http,
private toasterService: ToasterService,
private slimLoadingBarService: SlimLoadingBarService) {
super(http);
}
// tslint:disable-next-line function-name
$requestInterceptor(request: Request, methodOptions?: ResourceActionBase): Request {
this.slimLoadingBarService.start();
return request;
}
....
then I use this service like this:
@Injectable()
export class AppearanceApiService extends RestClient {
@ResourceAction({ path: '/main/appearance' })
get: ResourceMethod<{ type: string }, AppearanceResponse>;
@ResourceAction({ path: '/main/appearance', method: RequestMethod.Put })
update: ResourceMethod<types.Appearance, BaseResponse>;
}
appearanceApiService.get(
{ type: $transition$.params().type },
(response: AppearanceResponse) => {
!!('$resource' in response.$resource); // true
!!('$resolved' in response.$resolved); // true
!!('$observable' in response.$observable); // true
!!('$abortRequest' in response.$abortRequest); // true
appearanceDataService.appearance = response;
},
);
and then I send the response back using appearanceApiService.update
response
?@Melzar @maxkorz Please try updated version. It should be fine now. @maxkorz Answers:
$
please check lean
param in the readme$cleanData
method@troyanskiy thanks, it works.
lean
param removes $
from everywhere. But is it possible to remove $
from response
but keep it in ResourceResult<O>
? So I could do something like that:
public ngOnDestroy(): void {
if (this.apiRequest && !this.apiRequest.$resolved) {
this.apiRequest.$abortRequest();
}
}
public getMyStuff(): void {
this.apiRequest = this.myApiService.query(
(response) => {
console.log(Object.keys(response)); // I don't want to have $ variables here
},
); // but I want $ variables in ResourceResult
}
@maxkorz personally I for one of the projects I'm using it like that But in that case you don't have $ variables at all.
@ResourceParams({
toPromise: true, // all methods will return promise instead of ResourceResult. ResourceResult will be return by promise
lean: true // removes from resource result $
})
export class MyRes extends Resource {
@ResourceAction({
path: '/item',
toPromise: true, // or you can add that per method
lean: true // that also can be added per method
})
getItem: ResourceMethodPromise<void, any>;
}
public async getMyStuff(): void {
const data = await this.myRes.getItem();
}
Or simply clean response using Resource.$cleanData
static method;
public ngOnDestroy(): void {
if (this.apiRequest && !this.apiRequest.$resolved) {
this.apiRequest.$abortRequest();
}
}
public getMyStuff(): void {
this.apiRequest = this.myApiService.query(
(response) => {
response = Resource.$cleanData(response); // it will create new object without $
},
); // but I want $ variables in ResourceResult
}
Hello, I'm not sure if I found an issue or is it by design.
I'm receiving following error
Steps to reproduce it is pretty easy.
First you have to fetch data ( for example single object by id ) using ResourceMethod
and then received object by for example
post again like
myservice.update(myItem).$observable.subscribe....
From my research I've noticed that when we are fetching data with use of ResourceMethod then received object has additional property $resource and then again if we post the same object then this property cause circular error. If we remove manually $resource property like
delete item['$resource']
then everything is fine.So my question here is if this behaviour is by design or is it a bug? Is there any chance to avoid this error by using ResourceMethod response?
My Project dependencies
This behaviour has been introduced with following commit
https://github.com/troyanskiy/ngx-resource/commit/4f2319a2e5443722eeffa7f1f0901916287ee197
I would be grateful for any help provided on that matter :)