1
votes

I have a post method in my angular app that has a null body. The in memory web api keeps giving the null does not have item.id error, but if I pass {} instead of null it works fine.

I don't want to have to change my actual post call for the in memory web api testing, so was wondering if there is any way to make my in memory web api not try to add anything or convert the null to {}. Basically my post method doesn't do much besides ping the server

1
of course, it will give u null error for item.id, you are accessing id property of a null value. when you pass {} and you access its property id, id is null not the item. - Akanksha Gaur
Yes, my question was whether there was any way to make the in memory web api not try to access the id property if it is null - aks94
try sending undefined instead of null. in-memory-web-api has undefined checks but not for null - Akanksha Gaur
thanks, but unfortunately getting the same error with undefined as well - aks94
@aks94 did you find a solution for this problem? - Ash

1 Answers

1
votes

I had the same problem as yourself. After playing around with the in-memory-web-api trying to override the post method similar to the readme notes for the parseRequestUrl I didn't have much success; only getting part way there.

Instead I've opted to use the Angular HttpInterceptor which seems like the logical decision now looking back.

Create a HTTP interceptor class that checks for a null POST body. If found, clone the request as it should be considered immutable and set the body to an empty object {}. If there is a POST body then continue on with the request as normal. Then import the interceptor in the AppModule and include in the modules providers array.

Create file http-post-interceptor.ts

import { Injectable } from '@angular/core';
import {
 HttpEvent,
 HttpInterceptor,
 HttpHandler,
 HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class HttpPostInterceptor implements HttpInterceptor {
  constructor() {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // if request body is falsey
    if (!req.body) {
      // clone immutable request and set empty POST body
      const request = req.clone({ body: {} });
      // continue with our modified POST request
      return next.handle(request);
    }
    // else continue with the unmodified POST
    return next.handle(req);
  }
}

Import the HttpPostInterceptor and HTTP_INTERCEPTORS into app.module.ts

// ...
import { /*...*/ HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpPostInterceptor } from './http-post-interceptor';
// ...

@NgModule({
  // ...
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: HttpPostInterceptor, multi: true }
  ],
  // ...
})

That's all there is to it.

This has solved the problem for me in my local environment so I'm no longer getting the errors noted in your question.

Disable in production build

Since in-memory-web-api is typically a non-production tool you may want to exclude this in your production build. Do so by importing your environment settings and performing a check if the production property is true or false. This could be done either in the interceptor or the module as per your needs. An example below is showing this via the AppModule.

Import your environment settings into app.module.ts

// ...
import { environment } from '../environments/environment'; 
// ...

@NgModule({
  // ...
  providers: [
    environment.production ? [] :
      { provide: HTTP_INTERCEPTORS, useClass: HttpPostInterceptor, multi: true }
  ]
  // ...
})

Note: some import paths may differ depending on your project structure and if you are using Angular 6, notably the Observable import from rxjs