-
Notifications
You must be signed in to change notification settings - Fork 483
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: allow awaiting Promises on properties #549
Comments
A related fix has been merged in #463, which prevents a JS error from happening when a Promise is found on a property during transformation. |
A related fix has been merged in #262. |
This comment has been minimized.
This comment has been minimized.
I have this User class that has an
From what I analyzed the |
I think we have three distinct requirements, that are all blocked by the fact that class-transformer does not support promises:
For (3), the same solution applied to (1) may be applied here. If we are to reuse the sync part of the library (and depending on the order in which we apply the promise-based part), the promises in the input object must be ignored, and be passed as-is. I'm not sure how the library deals with promises today; if it blocks promises, or raises errors when it sees one, that behaviour may perhaps be deactivated by a new flag, like To indicate which DI container to use, we could repeat a mechanism similar to the one implemented by class-validator. But still, I think that some improvements could be made to the API surface to support for DI at the decoration level. It doesn't need to go into a high level of specificity. All DI containers support retrieving dependencies by token, so that could be the minimum support we could add, as a new decorator. For example: export interface InjectedTransformOptions {
token: string | symbol | () => (string | symbol | Constructor<T> | AbstractClass<T>);
}
export function InjectedTransform(options: InjectedTransformOptions): PropertyDecorator {
// ...
} Then, before returning the transformed object to the user, we can check for the One disadvantage of this approach, though, is the fact that there'll be no way to order how or when these promises will be resolved. For those that, like me, cannot wait for promise support to land in class-transformer, I made some proof-of-concepts for NestJS DI support here. I haven't tested them yet, though; I'm sharing just to have some early feedback:
Advantage of the sync version is that it does not introduce much, and uses the very same sync API class-transformer presents to us today. Disadvantage is that you'll need to await on properties yourself, in an explicit step, after calling Advantage of the async version is that it does all the promise resolution for you, with or without a dependency injection (there're two different types of async transformers: async function and injected object). Dependency injection also supports scoped providers. Disadvantage is the introduction of new metadata, and new transform functions (starting with |
This issue still exists on 19 September, so I've solved it in a such way, maybe it will help someone. The main idea is to give objects without promises to the class transformer. |
I was having issues with GraphQLUpload and InputType |
In which version, promises work? I have issue using promises in Transform. |
Seems there will not be any progress on this. What libraries are others using for async serialization? I've looked at tools like https://www.npmjs.com/package/json-object-mapper and https://www.npmjs.com/package/json-api-serializer but neither seem to support async methods. |
It is completely nuts that a simple feature like this is missing in a library that is used by so many people. |
IMHO, this is not needed in properly crafted software. You should resolve all your data first, then transform. |
It still depends, right? There are cases you've just joined a long-running project and you can't decide or change how it was already designed. There are also personal tastes added up into a mix of decisions we made while designing a software, just saying :) If it's a requested features by a reasonable number of users / interests since years, why should we avoid extending the library to cover more use cases? |
Sure, got the point of such request. But it is about changing the whole public interface of this library to async. About "reasonable number of users" is always a problem of perspective :) I believe that there is reasonable number of users against this change, which probably is even bigger in numbers, but those are just not interested in taking part in this conversation ;) |
hmmm, my bad, I wasn't fully aware of this changing the whole library interface. I thought it was just My use case is transforming then validating a couple of my DTOs with nestjs before they even reach into my controller code, some of the transformation need async here and there. So this is the feature I'm waiting for. IMO we already had async validations with |
If you have an PlainLiteralObject back from instanceToPlain, you can just await the returned promises. this is the code in TransformOperationExecutor (isPromise(value) && !isMap) {
return new Promise((resolve, reject) => {
value.then(
(data: any) =>
resolve(this.transform(undefined, data, targetType, undefined, undefined, level + 1)),
reject,
);
});
} So if you await all values downstream it just works :) const awaitAllValues = async (obj: PlainLiteralObject) => {
if (!obj) {
return obj;
}
obj = await obj;
if (Array.isArray(obj)) {
for (const vl of obj) {
await awaitAllValues(vl);
}
return obj;
} else if (typeof obj === 'object') {
for (const [key, value] of Object.entries(obj)) {
obj[key] = await awaitAllValues(await value);
}
}
return obj;
};
return await awaitAllValues(instanceToPlain(ObjectInstance, options)); |
Description
There had been multiple requests about allowing awaiting promises during transformation. This issue is the tracking issue for the feature.
Proposed solution
Our API is currently sync and doesn't support async operations. The main requirements for the feature should be:
Promise
only response)We have multiple options to implement this:
fnAsync
method for all validation methodQuestions
How to handle promises in sync validation?
Generally, I think Promises in sync mode should be converted to
undefined
. However, we may want to add a transformation option that forbids promises in sync validation. This can be useful for users who use both methods.to be continued... this issue will be expanded with more implementation details before work starts
Please do not comment non-related stuff like
+1
orwaiting for this
. If you want to express interest you can like the issue.The text was updated successfully, but these errors were encountered: