-1

I am trying to upload an image file to my backend. However no matter the device (Android or IOS) I am getting a 400 error code. Don't know what I am doing wrong but i follow the documentation on @nativescript/background-http for uploading files

  • Nativescript Version: 7
  • Angular Version: 10
  • Issue on Both Android and IOS

CONSOLE LOG:

        
    shared.service.ts:48 File exists: true
    shared.service.ts:54 photo Saved: true
        
    Photo File: {
       "_path": "/data/user/0/org.nativescript.WorkoutTracker/files/Stone0.png",
       "_name": "Stone0.png",
       "_extension": ".png"
    }
        
    shared.service.ts:164 upload progress: 0.1%
    shared.service.ts:164 upload progress: 100.0%
    profile.component.ts:83 
    Server error: {
          "eventName": "error",
          "object": {
            "_observers": {
              "progress": [
                {}
              ],
              "error": [
                {}
              ],
              "complete": [
                {}
              ]
            },
            "_session": {
              "_id": "img_upload"
            },
            "_id": "img_upload{1}",
            "_description": "Uploading",
            "_upload": 120143,
            "_totalUpload": 120143,
            "_status": "error"
          },
          "error": null,
          "responseCode": 400,
          "response": {}
        }
    
    

This is the code:

imageUpload(photo: File, token: string) {
        let observer: Subscriber<Image>;
        const imageUpload$ = new Observable<Image>(
            (observ) => (observer = observ)
        );

        const imgUrl = apiDomain + images;

        console.log("Filee exists:", File.exists(photo.path));
        const params = [];
        const param = {
            name: "photo",
            filename: photo.path,
            mimeType: "image/jpeg",
        };
        params.push(param);

        const headers = {
            // "Content-Type": "application/protobuf",
            'Authorization': `Bearer ${token}`,
            "Content-Type": "application/octet-stream",
            // 'Accept': 'application/protobuf',
            // "File-Name": photo.name
        };

        // const headers = new HttpHeaders({
        //     Authorization: "Bearer " + token,
        //     // 'Accept': 'application/protobuf',
        //     "Content-Type": "application/protobuf",
        //     // "Content-Type": "application/octet-stream",
        // });
        // console.log("Content-Type:", headers);

        this.fileUpload<Image>(imgUrl, { requestType: "POST", headers }, params).subscribe(
            (res) => {
                if (res instanceof Image) {
                    observer.next(res);
                }
            },
            (err) => {
                observer.error(err);
            }
        );

        return imageUpload$;
    }
fileUpload<E>(uri: string, body: { requestType?: "POST" | "GET", headers}, params: any[]) {
        let observer: Subscriber<E | ProgressEventData | ResultEventData>;
        const request$ = new Observable<E | ProgressEventData | ResultEventData>((observ) =>(observer = observ));

        const reqSession = session("file-upload");

        const request = {
            url: uri,
            method: body.requestType ?? "POST",
            description: "Uploading",
            headers: body.headers,
        };

        console.log("request", request);
        console.log("params", params);

        const task = reqSession.multipartUpload(params, request);

        task.on("progress", (evt) => {
            console.log(
                "upload progress: " +
                    ((evt.currentBytes / evt.totalBytes) * 100).toFixed(1) +
                    "%"
            );
            observer.next(evt);
        });

        task.on("error", (evt) => {
            console.log("upload error");
            observer.error(evt);
        });

        task.on("complete", (evt) => {
            const event: any = evt;

            if (global.isIOS) {
                if (event.responseCode >= 200 && event.responseCode < 300) {
                    console.log("success", event);
                    const object: E = event.object;
                    observer.next(object);
                    observer.complete();
                } else if (
                    event.responseCode >= 400 &&
                    event.responseCode < 500
                ) {
                    const errorResp: ErrorEventData = event;
                    observer.error(errorResp);
                }
            } else if (global.isAndroid) {
                console.log("success", event.responseCode, event);
                const object: E = event.object;
                observer.next(object);
                observer.complete();
            }
        });

        return request$;
    }

1 Answers1

0

The 400 error was due to the name in the params for me

const param = {
            name: "photo", // This needed to match the name in the backend
            filename: photo.path,
            mimeType: "image/jpeg",
};