Closed omaziarz closed 1 month ago
I have a question. Is it really okay just by writinng the string path? It actually converted to the File
instance?
Can you show me an example creating the FormData
instance in the React Native with exact type?
I want to know about below type exactly. Is it really okay with primitive object instance? Or needs another class type?
{
uri: 'path-to-file-on-the-phone',
name: 'file-name',
type: 'image/png',
}
yes sure
React-Native
import { SafeAreaView, Button } from 'react-native';
export default function HomeScreen() {
const handlePress = async () => {
const body = new FormData();
body.append('file', {
name: 'image.png',
type: 'image/png',
uri: 'https://picsum.photos/500/500', // this can be any uri so local phone uri or internet
});
fetch('http://192.168.0.106:3050/upload', {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
},
body,
});
};
return (
<SafeAreaView
style={{
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
gap: 100,
}}
>
<Button title="changePP" onPress={handlePress} />
</SafeAreaView>
);
}
Fastify Server
import fastify from 'fastify';
import multipart from '@fastify/multipart';
const server = fastify();
server.register(multipart);
server.post('/upload', async (req, res) => {
const file = await req.file();
console.log((await file?.toBuffer())?.byteLength);
});
server.listen({
port: 3050,
host: '0.0.0.0',
});
The value of console.log((await file?.toBuffer())?.byteLength);
will be > 0, fastify handles it without any added logic
In the @nestia/sdk
, both client and server side must have the same type.
Therefore, I don't know how to solve this problem especially for the React Native.
For a while, how about solving this problem by hard casting to the File
class in the RN client side?
I will consider the adapt the File | IFileUri
type in the @TypedFormData.Body()
decorator, but need your suggestion.
what do you mean by hard casting ? using the as
keyword ?
If the File | IFileUri
solution is doable for you then IFileUri should be the following :
interface IFileUri {
uri: string;
name: string;
type: string;
}
these are the only required properties.
I'll solve this problem by making below type.
By the way, I'm considering below type names.
@omaziarz, will you determine the type name?
FormDataInput
FormDataRequest
FormDataProps
export type FormDataInput<T extends object> =
T extends Array<any>
? never
: T extends Function
? never
: {
[P in keyof T]: T[P] extends Array<infer U>
? FormDataValue<U>[]
: FormDataValue<T[P]>;
};
type FormDataValue<T> = T extends File ? T | FileProps : T;
interface FileProps {
uri: string;
name: string;
type: string;
}
I'll solve this problem by making below type.
By the way, I'm considering below type names.
@omaziarz, will you determine the type name?
FormDataInput
FormDataRequest
FormDataProps
export type FormDataInput<T extends object> = T extends Array<any> ? never : T extends Function ? never : { [P in keyof T]: T[P] extends Array<infer U> ? FormDataValue<U>[] : FormDataValue<T[P]>; }; type FormDataValue<T> = T extends File ? T | FileProps : T; interface FileProps { uri: string; name: string; type: string; }
Well i'm not really good with names myself haha but
FormDataInput
sounds good to me. And hit me up when you need me to test it before publishing a new version. Thanks for your reactivity :)
Upgrade to latest. Would works properly.
@samchon just to confirm with you that it works thank you very much !!
Feature Request
In react native the only way to send Files in a multipart request is by doing the following :
this doesn't work :
As expected when using the first approach I will get the following error when using the custom object:
I think that to support all environments, validation inside
@TypedFormData.Body()
should support the custom object as a valid Blob because, at least, in fastify the custom object works the same way as a Blob without any additional handling needed