Search code examples
angulartypescriptangular-httpclient

Send just the model PK (or any other field) for nested model in Angular


Having the following sample models:

interface User {
  id: string
  organization: Organization
}

interface Organization {
  id: string
}

When I send a request, for example:

const user = new User("abc", new Organization("xyz"))
httpClient.post<User>(url, user)

Understandably, it looks like this:

{
  "id": "abc",
  "organization": {
    "id": "xyz"
  }
}

How can I send a request that looks like the following, instead?

{
  "id": "abc",
  "organization": "xyz"
}

I was hoping there would be some kind of mechanism to transform a request in HttpClient, but I can’t find anything.

Another approach was to convert the User to a plain JS object and manipulate it, but I can’t figure out how to do it:

const user = new User("abc", new Organization("xyz"))
const data = Object.assign({}, user);

data.organization = data.organization.id; // error, can’t assign string to Organization

So data is still a User, not a plain JS object.

What’s the best way to achieve it?


Solution

  • I found one solution but I’m not 100% happy with it. I won’t accept it for now, in case someone can offer a better one.

    Edit: marked as accepted answer.

    const user = new User("abc", new Organization("xyz"));
    
    // clone the `user` object as I don’t want to modify the original
    // (this step is optional)
    const data = Object.assign({}, user);
    
    // overwrite the `organization` property on the object
    // with the value of `organization.id`
    Object.assign(data, { organization: data.organization.id });
    
    httpClient.post<User>(url, data)
    

    To keep it clean, I added it as a method on the User class:

    class User
    {
        constructor(
            id: string,
            organization: Organization
        ) { }
    
        asRequestData()
        {
            const data = Object.assign({}, this);
            Object.assign(data, { organization: data.organization?.name });
    
            return data;
        }
    }
    
    httpClient.post<User>(url, user.asRequestData())