AutoMapper icon indicating copy to clipboard operation
AutoMapper copied to clipboard

Error: Impossible to use asynchronous mapping using automapper.map(); use automapper.mapAsync() instead

Open LWB-MatJ opened this issue 7 years ago • 14 comments

Hi,

I'm getting the following error even though my mapping function is not async. I'm using the mapFrom method.

Error: Impossible to use asynchronous mapping using automapper.map(); use automapper.mapAsync() instead

I've tracked the issue down to automapper.js in the dist folder.

See below. The async property is getting set to true if there are 2 parameterNames. I'm not sure what parameterNames is, it looks like a serialization of the mapping function. There is nothing async in my mapping function.

automapperasyncissue automapperasyncissue

Can you explain to me what this is trying to achieve or a way i can avoid this issue?

thanks Mat

LWB-MatJ avatar Jul 11 '17 23:07 LWB-MatJ

I'm having trouble uploading a screenshot. It's located on line 129 in the method AutoMapperHelper.getMappingMetadataFromTransformationFunction in file dist/automapper.js

LWB-MatJ avatar Jul 12 '17 00:07 LWB-MatJ

I was using an arrow function and this throws the getFunctionParameters out of wack. I will change to using proper functions

LWB-MatJ avatar Jul 12 '17 00:07 LWB-MatJ

Hi Matt,

Could you please post your mapping code resulting in this exception? It would help investigating and/or clarifying the problem you are facing ;) ...

Cheers, Bert

loedeman avatar Jul 12 '17 06:07 loedeman

Hi Bert,

Using arrow functions it doesn't seem to be determining the number of parameters correctly see below

const mapFromNullable = (opts, field) => {
  if (opts.sourceObject[field]) return opts.sourceObject[field]
  return ''
}

const automapper = require('automapper-ts')

automapper.createMap('input', 'output')
  .forMember('outputProp', opts => mapFromNullable(opts, 'input'))
  .ignoreAllNonExisting()

console.log(automapper.map('input', 'output', { inputProp: 'Test Prop' }))

To be honest it's no big deal. I've converted it to use explicit functions like below and it's fine

function (opts) { mapFromNullable(opts, 'input') }

thanks Mat

LWB-MatJ avatar Jul 13 '17 00:07 LWB-MatJ

I found the root of this issue. Lucky me, I was about to register the same issue with forSourceMember.

In function AutoMapperHelper.getFunctionParameters, the author intends to count the number of parameters of forMember's callback:

opts => mapFromNullable(opts, 'input')

, which in this case should be 01 (opts). However the function makes mistake and counts number of params in mapFromNullable(opts, 'input') which yields 02. I can tell that the regular expression in AutoMapperHelper.getFunctionParameters mistakes mapFromNullable(opts, 'input') (with 2 input params) for opts => mapFromNullable(opts, 'input') (with 1 input param).

In the time being, this is a working workaround:

function transformation(opts) {
  return mapFromNullable(opts, 'input');
}

automapper.createMap('input', 'output')
  .forMember('outputProp', opts => transformation(opts))
  // .forMember('outputProp', transformation) => Don't do this. Believe me 😃 
  .ignoreAllNonExisting();

hirikarate avatar Aug 04 '17 11:08 hirikarate

I experienced the same issue. Moving from arrow function expressions to function expressions fixed this for me as well.

gdovicak avatar Aug 09 '17 13:08 gdovicak

Hi @LWB-MatJ , @hirikarate and @gdovicak ,

I am unable to reproduce your issue using TypeScript. The TypeScript compiler compiles arrow functions to plain JavaScript functions at all times. At least, that is what happens with me. A couple of questions:

  1. Are you using Typescript to write front-end code?
  2. Which compiler target are you using? Is it possible that your resulting code still has arrow functions in it?

Number two would explain why changing arrow functions to plain JavaScript functions would change behavior at your end...

I hope to hear from you soon.

Cheers, Bert

loedeman avatar Sep 01 '17 15:09 loedeman

Actually I am using automapper-ts for NodeJS backend code and it works pretty well except this issue (kind of minor one). Here is my tsconfig: {

	"compilerOptions": {
		"target": "es2016",
		"module": "commonjs",
		"moduleResolution": "node",
		"sourceMap": false,
		"emitDecoratorMetadata": true,
		"experimentalDecorators": true,
		"removeComments": false,
		"noImplicitAny": false,
		"allowSyntheticDefaultImports": true
	}
}

hirikarate avatar Sep 21 '17 04:09 hirikarate

I am doing the same as @hirikarate and am not using Typescript. #2 would explain the issue I am seeing.

gdovicak avatar Oct 25 '17 14:10 gdovicak

Hi @hirikarate and @gdovicak ,

Unfortunately, AutoMapperTS does not fully support ES2016 (yet). The workaround in this scenario is to use a classic EcmaScript 5 function (e.g. function(opts) { ... }) instead for those mapping scenarios.

Please feel free to fix the problem and file a PR, should one of you have a little bit more spare time than I currently have.

Cheers, Bert

loedeman avatar Oct 25 '17 14:10 loedeman

This is absolutely still an issue. Particularly if you are using prettier/eslint/beautify, which will remove function(){} definitions and replace them with arrow functions.

rageycomma avatar May 10 '19 19:05 rageycomma

This is absolutely still an issue. Particularly if you are using prettier/eslint/beautify, which will remove function(){} definitions and replace them with arrow functions.

It is something terrible… I spent 2-3 hours to understand why Angular 7 to 9 migrated project doesn't work! Issue is still here and needs to be fixed!

DrJuriko avatar Sep 05 '20 21:09 DrJuriko

Hi, I used @gonza-lito fork on my project, and also I created PR there to fix incompatibility with arrow-functions. Maybe you can check that PR to fix the issue on your side. https://github.com/gonza-lito/AutoMapper/pull/1 The main change has been done here: https://github.com/gonza-lito/AutoMapper/pull/1/files#diff-e48398614b3d36beb47c5d3ae5f42b7e

nloznjakovic avatar Sep 08 '20 08:09 nloznjakovic

The main change has been done here: https://github.com/gonza-lito/AutoMapper/pull/1/files#diff-e48398614b3d36beb47c5d3ae5f42b7e

Thank you, works fine... in readme you wrote that "Remove global scope variable", please, provide at least a minimal description for suggested usage...

DrJuriko avatar Sep 08 '20 20:09 DrJuriko