lagoshny/ngx-hal-client

Error trying to instantiate null 'data' object, returned from server

Closed this issue · 2 comments

BaseResource.postRelation(...) should verify if the server sent back an actual object or an empty body before trying to instantiate it.

This line tries to instantiate null, because the server didn't return a data object.

return ResourceHelper.getHttp()
              .post(ResourceHelper.getProxy(url), body)
              .pipe(map(data => ResourceHelper.instantiateResource(Utils.clone(this), data)));

We use custom methods that return 204-No Content.
This is causing the following error:

core.js:4197 ERROR Error: Uncaught (in promise): TypeError: Cannot convert undefined or null to object

TypeError: Cannot convert undefined or null to object
at Function.keys ()
at Function.instantiateResource (lagoshny-ngx-hal-client.js:298)
at MapSubscriber.project (lagoshny-ngx-hal-client.js:633)
at MapSubscriber._next (map.js:29)
at MapSubscriber.next (Subscriber.js:49)
at MapSubscriber._next (map.js:35)
at MapSubscriber.next (Subscriber.js:49)
at FilterSubscriber._next (filter.js:33)
at FilterSubscriber.next (Subscriber.js:49)
at MergeMapSubscriber.notifyNext (mergeMap.js:70)
at resolvePromise (zone-evergreen.js:798)
at resolvePromise (zone-evergreen.js:750)
at zone-evergreen.js:860
at ZoneDelegate.invokeTask (zone-evergreen.js:399)
at Object.onInvokeTask (core.js:27418)
at ZoneDelegate.invokeTask (zone-evergreen.js:398)
at Zone.runTask (zone-evergreen.js:167)
at drainMicroTaskQueue (zone-evergreen.js:569)
at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:484)
at invokeTask (zone-evergreen.js:1621)

Reference:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5

For now we are monkey-patching the instantiateResource method. It's brutal, but works.

import {ResourceHelper} from "@lagoshny/ngx-hal-client";

ResourceHelper.instantiateResource = function (entity, payload) {
  if (payload == null) return null;                        // <<<----- Line PATCHED
  for (const key of Object.keys(payload)) {
    if (payload[key] instanceof Array) {
      for (let i = 0; i < payload[key].length; i++) {
        if (this.isEmbeddedResource(payload[key][i]) && this.embeddedResourceType) {
          // @ts-ignore
          payload[key][i] = ResourceHelper.createResource(new this.embeddedResourceType(), payload[key][i]);
        }
      }
    }
    else if (this.isEmbeddedResource(payload[key]) && this.embeddedResourceType) {
      // @ts-ignore
      payload[key] = ResourceHelper.createResource(new this.embeddedResourceType(), payload[key]);
    }
  }
  // @ts-ignore
  return ResourceHelper.createResource(entity, payload);
};

Hi @danielrsilveira, thanks for the issue. I fixed the bug in the 1.1.4 release.