How can I upload the photo in React Native Expo

52 views Asked by At

I am trying to upload the image in react native expo project on mac os(sonoma). I used Laravel for backend.

Here is react native code.

const onSave = () => {
        submit.next();
        if (!errors) {
            const advert = mapAdvert(props.advertId, advertEditor, profile);
            if (props.isUpdate) dispatch(updateAdvert(advert as unknown as IAdvert));
            else {
                setShowPeriodDialog(true);
            }
        } else {
            dispatch(
                showToast({
                    title: t('warning'),
                    message: t('invalid_data'),
                    type: 'error',
                }),
            );
        }
    };

export const updateAdvert = (advert: IAdvert) => ({
    type: ManageAdvertActions.UPDATE_ADVERT,
    data: advert,
});

const onUpdateAdvert$ = (actions$: Observable<IAction>) =>
    actions$.pipe(
        ofType(ManageAdvertActions.UPDATE_ADVERT),
        switchMap((action) =>
            ManageAdvertsService.updateAdvert(action.data).pipe(
                switchMap((result) => {
                    return [
                        updateAdvertSuccess(result),
                        showToast({
                            type: 'success',
                            title: i18next.t('success'),
                            message: i18next.t('advert_updated'),
                        }),
                        go('ManageAdverts'),
                    ];
                }),
            ),
        ),
    );

static updateAdvert(advert: IAdvert) {
        const formData = ManageAdvertsService.prepareFormDataPayload(advert);
        return super.postWithFile<IAdvert>(
            `${API_ROUTES.ADVERTS.ADVERTS_LIST}/${advert.id}`,
            formData,
        );
    }

private static prepareFormDataPayload(advert: IAdvert) {
        const formData = new FormData();
        const imageKeys = keys(advert).filter((key) => key.includes('image'));
        imageKeys.forEach((key: string) => {
            const file = advert[key];
            if (typeof file === 'string') {
                formData.append(key, file);
            } else if (file) {
                const uri = (advert[key] as ImageInfo).uri;
                const filename = uri.split('/').pop();
                formData.append(key, {
                    uri: Platform.OS === 'android' ? uri : uri.replace('file://', ''),
                    type: 'image/jpg',
                    name: filename,
                });
            }
        });
        const otherKeys = keys(advert).filter((key) => !key.includes('image'));
        otherKeys.forEach((key) => {
            if (advert[key]) formData.append(key, advert[key] as string);
        });
        return formData;
    }

static postWithFile = <T extends IBaseModel | unknown, TX = T>(
        uri: string,
        data: FormData,
        baseUrl: string = environment.apiUrl,
    ): Observable<TX> => {
        return from(
             Axios.post(baseUrl + uri, data, {
                 headers: {
                     accept: 'application/json',
                     'Content-Type': 'multipart/form-data',
                 },
             }),
        ).pipe(switchMap((response) => of(response.data)));
    };

Then here is backend code(Laravel)

public function update(Request $request, Advert $advert)
    {
        
        $request->merge([
            'show'          => (bool) $request->show,
            'wifi'          => (bool) $request->wifi,
            'delivery'      => (bool) $request->delivery,
            'terras'        => (bool) $request->terras,
            'children_area' => (bool) $request->children_area,
            'smoking'       => (bool) $request->smoking,
            'parking'       => (bool) $request->parking,
            'enabled'       => (bool) $request->enabled,
            'external'      => (bool) $request->external,
            'credit_card'   => (bool) $request->credit_card,
        ]);

        $this->checkIfOwner($request->user()->id, $advert);

        $this->validate($request, $this->_validationArray);

        if (!$request->website) {
            $advert->website = null;
        }

        $advert->update($request->except(
            [
                'image_1',
                'image_2',
                'image_3',
                'image_4',
                'image_5',
                'image_6',
            ]
        ));
        $entity = $advert;

        if ($request->file('image_1') != null) {
            $entity->image_1 = $this->_storeImage($request->file('image_1'), $entity);
        }
        if ($request->file('image_2') != null) {
            $entity->image_2 = $this->_storeImage($request->file('image_2'), $entity);
        }
        if ($request->file('image_3') != null) {
            $entity->image_3 = $this->_storeImage($request->file('image_3'), $entity);
        }
        if ($request->file('image_4') != null) {
            $entity->image_4 = $this->_storeImage($request->file('image_4'), $entity);
        }
        if ($request->file('image_5') != null) {
            $entity->image_5 = $this->_storeImage($request->file('image_5'), $entity);
        }
        if ($request->file('image_6') != null) {
            $entity->image_6 = $this->_storeImage($request->file('image_6'), $entity);
        }
        $entity->share_link = $this->_shareLink($entity);
        $entity->save();
        if (config('app.env') != 'local') {
            $entity = $this->_setCoordinates($entity);
        }


        return $this->showOne($entity, 200);
    }

In this code, If I request the form data without image, the backend receive the request and it is succeeded to update form data. But If I request the form data with image, request doesn't work and I can't see any request and response in console. Here is the result of data. enter image description here I've already tried to use the fetch instead of axios. But I can't see any result.

react: 18.0.0,
react-native: 0.69.6,
expo:46.0.0,
expo-image-picker: 13.3.1,
form-data: 4.0.0,
rxjs: 7.8.1,

If anyone have experience with solving this problem, please help me!

0

There are 0 answers