6

Have seen this but the question was unanswered. So asking this question again.

I was trying to implement a PUT. Which didn't work, I checked the requestInformationand response in responseInterceptor. It turns out that the control never reaches my responseInterceptor.

This is the http code:

put(url: string, body, options?:RequestOptionsArgs): Observable<StandardModelResponse>{
    console.log("inside put, url = ", url, " body = ", body);
    return this._http.put(url,body,this._updateRequestHeader(options)); 
}

The received log is:

enter image description here

My InMemoryDbService has a collection:

let sessionData = [
  {
    id: 1,
    loginActive: 0
  }
];

and it returns the collection like this:

return {sessionData}

I looked through the source, and yes indeed there is an implementation of post and put, but I could not find the in-memory-backend.service.ts file in my node-modules for debugging, instead a in-memory-backend.service.js is there. What is the right way to do this POST call, what am I missing here?

Community
  • 1
  • 1
Ashish Ranjan
  • 12,760
  • 5
  • 27
  • 51
  • It should work. You have an example that _doesn't_? And what's not working about it (meaning what's the result)? – Paul Samsotha Apr 11 '17 at 13:48
  • Check out [the source](https://github.com/angular/in-memory-web-api/blob/master/src/in-memory-backend.service.ts). Towards the bottom, you'll see the post and put methods implemented – Paul Samsotha Apr 11 '17 at 13:53
  • Thanks, checking out. Will let you know the status. – Ashish Ranjan Apr 11 '17 at 14:03
  • @peeskillet: Hi, I have updated my question, can you please have a look into it? – Ashish Ranjan Apr 11 '17 at 15:40
  • _"And what's not working about it (meaning what's the result)?"_ – Paul Samsotha Apr 11 '17 at 15:46
  • I have explained that. I don't get anything in my `responseInterceptor`. The collection, `sessionData` remains the same, although as shown in the log, I am sending `loginActive` as `1`. This is all, no errors come in the console. – Ashish Ranjan Apr 11 '17 at 16:17
  • Not sure the purpose of your interceptors. Take it out and what's the result? Maybe it is the problem – Paul Samsotha Apr 12 '17 at 03:53
  • Did that, no result as such! Didn't get any response. Just clarifying, the collection on which I am doing a put will actually be updated in the file (class extending InMemoryDb)? I don't see that in the code, all I see is a `new ResponseOptions()` with the updated array. – Ashish Ranjan Apr 12 '17 at 04:29
  • 4
    _"Did that, no result as such! Didn't get any response"_ You realize that the default for POST and PUT is to not return any response. This is based on common practices with REST: POST should just set Location header with created URI with 201 status; PUT should just return 204 status. Both with no body. You can configure the service to send back the body if you want. When you configure the module in your app, pass as a second argument `forRoot(Service, {post204: false, put204: false})` – Paul Samsotha Apr 12 '17 at 04:33
  • 1
    You can see all the possible configurtions [here in the source](https://github.com/angular/in-memory-web-api/blob/master/src/in-memory-backend.service.ts#L94) – Paul Samsotha Apr 12 '17 at 04:35
  • Many thanks, It took me so long to find that I was missing the `subscribe()` in my `save()`. Your comments were very helpful though. And its amazing how angular keeps the updated data in memory but doesn't write it to the file. – Ashish Ranjan Apr 12 '17 at 13:38
  • Damn... all of the GitHub links, in the question, and in these comments, take me to a Page Not Found screen. – Mike Gledhill Jul 06 '20 at 08:32
  • @MikeGledhill Try https://github.com/angular/angular/tree/11.1.x/packages/misc/angular-in-memory-web-api and specifically https://github.com/angular/angular/blob/11.1.x/packages/misc/angular-in-memory-web-api/src/interfaces.ts as the angular-in-memory-web-api has been rolled into angular – William Denman Jan 22 '21 at 21:28

2 Answers2

0

You can "override" (I am not sure if that is what is happening) the post method by adding it in your implementation of InMemoryDbService

import { InMemoryDbService } from 'angular-in-memory-web-api';
import { getStatusText, STATUS } from 'angular-in-memory-web-api/http-status-codes';
import { ParsedRequestUrl, RequestInfo, RequestInfoUtilities, ResponseOptions } from 'angular-in-memory-web-api/interfaces';
.....

  post(reqInfo: RequestInfo) {

  }
...

You can implement it to do something like the implementation of the get method like it is done here: source

I hope that helps. It seems to work :)

Abdulrahman Falyoun
  • 3,676
  • 3
  • 16
  • 43
Gryffe
  • 413
  • 1
  • 3
  • 9
0

It is a pretty old question but I have not found any answer describing how to patch InMemoryDbService needing to customize or fix a handler of a PUT or POST operation. As I have recently faced a similar situation, I have decided to post my solution here so that somebody might find it useful.

As has already been mentioned above, post and put functions can be overridden. For instance, the code below inserts a new item in the post method and updates an existing item in the put method

export class InMemoryDatabase extends InMemoryDbService {
  createDb() {
    const heroes = [
      {id: 1, name: 'Superman'},
      {id: 2, name: 'Biowulf')
    ];
    return { heroes };
  }

  post(reqInfo: RequestInfo) {
    var collection = reqInfo.collection;
    // process only requests as /api/object/:id
    if (!collection)
      return reqInfo.utils.createResponse$(() => {
        const options: ResponseOptions = { status: STATUS.NOT_FOUND };
        return this.finishOptions(options, reqInfo);
      });

    // insert an object to the collection
    let item = reqInfo.utils.getJsonBody(reqInfo.req)
    item["id"] = this.genId(collection);
    collection.push(item);

    // respond
    return reqInfo.utils.createResponse$(() => {
      const options: ResponseOptions =
      {
        body: item,
        status: STATUS.OK
      }
      return this.finishOptions(options, reqInfo);
    });
  }

  genId(collection: any): number {
    return collection.length > 0 ? Math.max(...collection.map(hero => hero.id)) + 1 : 11;
  }

  put(reqInfo: RequestInfo) {
    var collection = reqInfo.collection;

    // process only requests as /api/object/:id
    if (!collection || !reqInfo.id)
      return reqInfo.utils.createResponse$(() => {
        const options: ResponseOptions = { status: STATUS.NOT_FOUND };
        return this.finishOptions(options, reqInfo);
      });

    // update an object
    let item = reqInfo.utils.findById(collection, reqInfo.id);
    const body = reqInfo.utils.getJsonBody(reqInfo.req)
    Object.assign(item, body);

    // respond
    return reqInfo.utils.createResponse$(() => {
      const options: ResponseOptions =
      {
        body: item,
        status: STATUS.OK
      }
      return this.finishOptions(options, reqInfo);
    });
  }

  private finishOptions(options: ResponseOptions, { headers, url }: RequestInfo) {
    options.statusText = getStatusText(options.status);
    options.headers = headers;
    options.url = URL;
    return options;
  }
}
Evgeny Shmanev
  • 771
  • 6
  • 11