nartc / mapper

🔥 An Object-Object AutoMapper for TypeScript 🔥
https://automapperts.netlify.app/
MIT License
982 stars 88 forks source link

Mapped object is empty #502

Open MontyTRC89 opened 2 years ago

MontyTRC89 commented 2 years ago

Is there an existing issue for this?

Describe the issue

Hi. Even if I configure it correctly, mapped objects have all properties with default values instead of mapped values. I have tried to follow the also the tutorials on your documentation, but I get an empty object.

Models/DTOs/VMs

import {AutoMap} from "@automapper/classes";

export class User { @AutoMap() firstName: string;

@AutoMap()
lastName: string;

@AutoMap()
username: string;

password: string; // <- we purposely left this one out because we don't want to map "password"

@AutoMap(() => Bio)
bio: Bio;

}

export class Bio { @AutoMap(() => Job) job: Job;

@AutoMap()
birthday: Date;

@AutoMap()
avatarUrl: string;

}

export class Job { @AutoMap() title: string;

@AutoMap()
salary: number;

}

export class UserDto { @AutoMap() firstName: string;

@AutoMap()
lastName: string;

@AutoMap()
fullName: string;

@AutoMap()
username: string;

@AutoMap(() => BioDto)
bio: BioDto;

}

export class BioDto { @AutoMap() jobTitle: string;

@AutoMap()
jobSalary: number;

@AutoMap()
birthday: string;

@AutoMap()
avatarUrl: string;

}

Mapping configuration

createMap(mapper, Bio, BioDto); createMap(mapper, User, UserDto);

Steps to reproduce

No response

Expected behavior

I expect the mapped object having the values from source object.

Screenshots

No response

Minimum reproduction code

No response

Package

Other package and its version

No response

AutoMapper version

8.0.0

Additional context

No response

nartc commented 2 years ago

hi @MontyTRC89, thank you for reporting. Can you provide a little bit more context? What environment are you running? Node? Web? A reproduce repository would be appreciated

LynxWall commented 2 years ago

I'm running into the same issue. Migrated from version 6.3.1 following the migration guide. The only thing that works are the forMember functions. All other properties are empty on the destination after calling mapper.map().

Data is coming from axios call that populates a dto class. When mapping to a model class all of the destination properties that are not specifically initialized with forMember are missing.

I'm using profiles to configure the createMap calls and adding profiles to the mapper in the correct order.

Reverted back to 6.3.1 and all mappings work as expected.

maud08 commented 2 years ago

Same here. Using mapper to map a JSON object into a basic class containing strings. Only the forMember works. All unspecified @MapData() properties are empty / defaults. Using version 8.7.6.

nartc commented 2 years ago

Can anyone provide me with a reproduce repository? What environment are you running in?

nadhir-falta commented 2 years ago

Same issue here, new user new installation with latest version, matching fields are not being mapped unless manually mapped using the ForMember for each of those fields, which defeats the purpose of using the Automapper.

nartc commented 2 years ago

I can't solve the issue with "same issue here". Can someone provide a reproduce repo that I can clone and test?

Quentinmht commented 1 year ago

Hi @nartc,

I have the same problem so I decided to create a project to help you solve the problem. Automapper-bug

You can run :

This is the example on your documentation, classes are in a models folder in src and the code is in index.tsx.

If you run the project, you will see the empty object in the console, uncomment the part with the forMember and then you will see that the firstname is correctly mapped.

If you need something else, I will try to help !

Thanks a lot !

nartc commented 1 year ago

@Quentinmht thank you. The example on the documentations assume Nodejs. Browser might behave a little different. Nonetheless, I'll test out the reproduce and will report soon! Thanks again!

Quentinmht commented 1 year ago

Hi @nartc,

It would be so cool to be able to use it in web project. I suppose that this issue is only related to the browser as you said.

If you need help, don't hesitate !

lauridsen commented 1 year ago

Hi @nartc

Is there any update on this? We're having the same issue.

nbisges commented 1 year ago

Hi @nartc,

Just checking in if there is any ETA on resolving this issue.

Thank you

nartc commented 1 year ago

@Quentinmht @lauridsen @nbisges Sorry for taking so long on this.

I tested out the reproduction by @Quentinmht and can confirm the issue. The problem is Decorator Metadata doesn't seem to be emitted which fails @AutoMap() decorator. I'm not too familiar with setting up tsconfig for React projects (whether it's Vite or CRA) so I do need some help here (documentations would be nice)

nfjdu commented 1 year ago

@Quentinmht @lauridsen @nbisges Sorry for taking so long on this.

I tested out the reproduction by @Quentinmht and can confirm the issue. The problem is Decorator Metadata doesn't seem to be emitted which fails @AutoMap() decorator. I'm not too familiar with setting up tsconfig for React projects (whether it's Vite or CRA) so I do need some help here (documentations would be nice)

Have same issue. Here is my litle test project to show the issue (following your docs). package.json

{
  "name": "ts-automapper-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.ts",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@automapper/classes": "^8.7.7",
    "@automapper/core": "^8.7.7",
    "@types/node": "^20.6.0",
    "reflect-metadata": "^0.1.13"
  },
  "devDependencies": {
    "typescript": "^5.2.2"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "ES5",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "skipLibCheck": true
  }
}

index.ts

import { classes, AutoMap } from "@automapper/classes";
import { createMapper, createMap, forMember, mapFrom } from "@automapper/core";

export class User {
  @AutoMap()
  firstName!: string;

  @AutoMap()
  lastName!: string;

  @AutoMap()
  username!: string;

  password!: string; // <- we purposely left this one out because we don't want to map "password"
}

export class UserDto {
  @AutoMap()
  firstName!: string;

  @AutoMap()
  lastName!: string;

  @AutoMap()
  fullName!: string;

  @AutoMap()
  username!: string;
}

const mapper = createMapper({ strategyInitializer: classes() });

createMap(
  mapper,
  User,
  UserDto,
  // compute property
  forMember(
    (d) => d.fullName,
    mapFrom((s) => s.firstName + " " + s.lastName),
  ),
);

const user = new User();
user.firstName = "Chau";
user.lastName = "Tran";
user.username = "ctran";
user.password = "123456";

const dto = mapper.map(user, User, UserDto);

console.log(dto);

Run, using tsx : image

Any suggestions? Can send project if needed, and answer on any questions that will help

p.s. Another interesting thing: everything works fine in this little codesandbox . I have no idea why) p.s.2. Switched from tsx to ts-node , now it works as expected..