Class-transformer: Alias names / Different keynames after serialization

Created on 11 Jan 2018  路  5Comments  路  Source: typestack/class-transformer

The use case:
I use this library for a REST API wrapper where I map the returned JSON responses to my classes. I am struggling with just one specific case.

The REST Api returns a cardName, but unfortunately no cardId which could be used to retrieve the cardName. However I can resolve the cardId by a given cardName and I highly prefer to store cardIds instead of the cardNames in my database.

The code:

function cardResolver(cardNameOrId: string | number): number {
  // If we serialize a previously deserialized object we will already get the cardId instead of a name
  if (typeof cardNameOrId === 'number') {
    return <number>cardNameOrId;
  }

  return CardHelper.getCardByName(cardNameOrId).id;
}

@Exclude()
export class BaseCard {
  @Transform(cardResolver)
  @Expose({ name: 'name' })
  public id: number;
}

The problem:
This requirement is a challenge though, because now the library is supposed to handle two different schemas. One is the REST Api which returns the cardName and the other is my database which returns the cardId.

While my @Transform function is not an issue (it can handle both json inputs and recognizes the difference using the type), I need some sort of alias, since the input json can be either:

{ cardName: 'Goblin Barrel' }

or

{ cardId: 260000013 }

My question:

Can I achieve this with the given library features or does it make sense to add an alias feature?

decorators feature

Most helpful comment

Hi @weeco!

Thanks for the detailed report!

In your example, you use id but then you reference your inputs as cardId and cardName.
Is this correct?

Based on your description, I would expect the inputs being id and cardName and you want to add something like an @Alias decorator, what checks if there is an id property on the object and if not, it tries to add it from the cardName property? Like:

@Alias({ from: 'cardName' }, { toClassOnly: true })
@Transform(cardResolver)
public id: number;

Effect:

// input => value
{ id: 342 } => { id: 342 }
// input => value (via alias then transform)
{ cardName: 'name-of-car' } => { id: 342 }

Did I understand you correctly? If this is your desired goal, there is no way of doing this at the moment.

However, this request makes sense and there is already a similar request in #99. So this can be implemented, but later, first I want to finish class-validator and move to class-transformer after.

All 5 comments

Hi @weeco!

Thanks for the detailed report!

In your example, you use id but then you reference your inputs as cardId and cardName.
Is this correct?

Based on your description, I would expect the inputs being id and cardName and you want to add something like an @Alias decorator, what checks if there is an id property on the object and if not, it tries to add it from the cardName property? Like:

@Alias({ from: 'cardName' }, { toClassOnly: true })
@Transform(cardResolver)
public id: number;

Effect:

// input => value
{ id: 342 } => { id: 342 }
// input => value (via alias then transform)
{ cardName: 'name-of-car' } => { id: 342 }

Did I understand you correctly? If this is your desired goal, there is no way of doing this at the moment.

However, this request makes sense and there is already a similar request in #99. So this can be implemented, but later, first I want to finish class-validator and move to class-transformer after.

Yes you understood it perfectly well, that's exactly the desired behaviour.

Hi, is this @Alias decorator available?
I've the same situation, an API exposes an attribute "@id" but I would like to use as "id" attribute within my Class.
Am I missing something?

Thank you!!

Wonder if this can be done, 2 years pasted and it feels like it'd be a handy feature :)

Posting on issues asking whether it will be added will never make the process faster. Today I spent 10 hours answering questions which at least a third of them doesn't even take the time to read the documentation. So if you want to make this feature get implemented faster, you can always

  • implement it yourself
  • answer questions so I actually have any time to code
Was this page helpful?
0 / 5 - 0 ratings

Related issues

lazarljubenovic picture lazarljubenovic  路  6Comments

gregsolo-intent picture gregsolo-intent  路  5Comments

NathanHazout picture NathanHazout  路  5Comments

sebastian-zarzycki-es picture sebastian-zarzycki-es  路  6Comments

leon19 picture leon19  路  5Comments