Skip to content
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

Handle response message #16

Closed
PanayotCankov opened this issue May 25, 2016 · 25 comments
Closed

Handle response message #16

PanayotCankov opened this issue May 25, 2016 · 25 comments

Comments

@PanayotCankov
Copy link
Contributor

...

https://groups.google.com/forum/#!topic/nativescript/71SOZAGwo_g

As I mentioned there, your plugin fits our needs in nearly all points. We just need to process our own Server-response in the NativeScript-App.
I analyzed the plugin code and the android-fileupload-service. The Java-code seems to pass the server response message and the response code.

intent.putExtra(STATUS, STATUS_COMPLETED);
intent.putExtra(SERVER_RESPONSE_CODE, responseCode);
intent.putExtra(SERVER_RESPONSE_MESSAGE, filteredMessage);
In the onCompleted-Event of your ProgressReceiver, you get the responseCode and the responseMessage, but you do not process this data.

...

Regards,
Felix
@ComputerTinker
Copy link

First, thank you for this plugin. Second, I would also love to have the ability for a response message from the server to be passed back so that, if something goes wrong on the server, a reason for the error can be displayed to the end user.

In the meantime, can you tell me how the module's error event is currently being triggered? I thought that I could set the HTTP status code of the server script to be 404 or 422 and that would trigger bg-http's error event, but it does not seem to be working that way. Any help appreciated. Thanks!

@dondragon2
Copy link

Is there any implementation for this as yet? I am uploading a file to parse server where the server returns a json object containing the url for the file which is needed by my app.

@neopablix
Copy link

How can I get the response from the server? That will be great

@davecoffin
Copy link

I have a similar situation as dondragon2. I cant currently utilize any data that my api sends back after a successful upload, like a photo id created in my photos table for example. Are there plans to implement this enhancement?

@developper89
Copy link

`URLSessionDataTaskDidReceiveData(session, dataTask, data) {
//console.log("URLSessionDataTaskDidReceiveData");
// we have a response in the data...

let jsonString = new NSString({ data: data, encoding: NSUTF8StringEncoding });
let json = JSON.parse(jsonString.toString())
// do what you want with your data
console.log(JSON.stringify(json))

}`

@davecoffin
Copy link

THANK YOU @developper89 🌮🌮🌮🌮🌮🌮🌮🌮🌮🌮🌮🌮🌮🌮🌮🌮🌮🌮🌮🌮🌮

@davecoffin
Copy link

FYI for all who find this thread, until @PanayotCankov releases an official enhancement, here's how you can get access to the data via the task in your models. This is only for iOS, mind you:

In background-http.ios.js:

    URLSessionDataTaskDidReceiveData: function (session, dataTask, data) {
        var jsTask = getTask(session, dataTask);
        let jsonString = new NSString({ data: data, encoding: NSUTF8StringEncoding });
        let json = JSON.parse(jsonString.toString());
        jsTask.notify({ eventName: "responded", object: jsTask, data:json });
    },

You can call the eventName whatever you want. I perform all my done uploading operations when that event is fired, for example:

task.on("progress", logEvent);
task.on("error", logEvent);
task.on("complete", logEvent);
task.on("responded", logEvent);
function logEvent(e) {
    var rtn = {
        "status": e.eventName
    }
    if (e.eventName == 'complete') {
        console.log('upload completed');
    } else if (e.eventName == 'error') {
        if (callBack) callBack(rtn);
    } else if (e.eventName == 'progress') {
        if (updateProgressFn) {
            updateProgressFn({uploaded: e.object.upload, total: e.object.totalUpload});
        }
    } else if (e.eventName == 'responded') {
        rtn.data = e.data;
        console.log('the server has responded with data.');
        if (callBack) callBack(rtn);
    }
}

@Daxito
Copy link
Contributor

Daxito commented Oct 14, 2016

@davecoffin I found an issue with this code, basically since Tasks are stored as a WeakMap (line 187 of that file) I am losing the "task" sometimes but very often, so when I get my response back the task is not there anymore and what I get back is new Task instead, I had to get rid of the WeakMap, I am thinking about making a PullRequest and see if it gets approved by also using your approach along with my "fix"

Daxito pushed a commit to Daxito/nativescript-background-http that referenced this issue Oct 14, 2016
 and fixes
an issue with Tasks disapearing
when using a WeakMap (NativeScript#16)
Daxito pushed a commit to Daxito/nativescript-background-http that referenced this issue Oct 20, 2016
@friedolinfoerder
Copy link
Contributor

How does this work for android? Is there are solution or a workaround?

@friedolinfoerder
Copy link
Contributor

I've added the server response to the complete event arguments and created a pull request

@mshanak
Copy link

mshanak commented Mar 10, 2017

how to read server response data?

@AceTheFace
Copy link

The event provided to the "complete" callback contains the response:

task.on("complete", this.uploadComplete);

  private uploadComplete(completeEvent) {
         console.log(completeEvent.response.getBodyAsString());
  }

@Ericky14
Copy link

@AceTheFace Does that solution still work?
I tried using it and it doesn't seem to work for me.
This is the result:
screen shot 2017-05-17 at 10 26 32 pm

@developper89
Copy link

@Ericky14
task.on("responded", (e) => { let res = JSON.parse(e.data) })

@Ericky14
Copy link

Ericky14 commented May 18, 2017

@developper89
Actually, I still get the same thing, just a null character.
Is there any way I can debug this or know what's going on? It doesn't show up on Network Requests when running tns debug
The complete event fired fine I think, no errors.

{"eventName":"complete","object":{"_observers":{"progress":[{}],"error":[{}],"complete":[{}],"responded":[{}]},"_session":{"_id":"image-upload"},"_id":"image-upload{1}","_description":"{ 'uploading': googlelogo_color_160x56dp.png }","_upload":10590,"_totalUpload":10590,"_status":"complete"},"response":{}}

@davecoffin
Copy link

@Ericky14 It looks like you are tying into the complete event, the event that returns data is "responded".

@Ericky14
Copy link

Ericky14 commented May 18, 2017

@davecoffin
I know, I put that excerpt just to show the complete event fires without any error.
This is what I did:

    task.on('responded', e => {
        console.log(JSON.parse(e.data));
    });

But I believe it is most likely a problem with the back-end. The back-end works for uploading from web, but not from mobile with nativescript.

@davecoffin
Copy link

@Ericky14 Your problem appears to be that you are logging a json object. You are probably getting the data just fine, but you cant console.log an object. Try this:

    task.on('responded', e => {
        console.dir(JSON.parse(e.data));
    });

@davecoffin
Copy link

@Ericky14 To your point about uploading from web vs nativescript, if you can interact with your API using Postman, you should be able to from your app. What authentication does your server use? To get set up I'd write a method in your backend to return a string with no authentication, just as a proof of concept. Once your app is communicating with your backend you know that your problem exists in your execution.

@peterbsmyth
Copy link

peterbsmyth commented Nov 14, 2017

I get errors unless I modify the code to be what @developper89 posted:

BackgroundUploadDelegate.prototype.URLSessionDataTaskDidReceiveData = function (session, dataTask, data) {
        dispatch_async(main_queue, function () {
            var jsTask = Task.getTask(session, dataTask);
            var jsonString = new NSString({ data: data, encoding: NSUTF8StringEncoding });
            jsTask.notify({ eventName: "responded", object: jsTask, data: JSON.parse(jsonString.toString()) });
        });
    };

@acharyaks90
Copy link

How to ready in case of error , it does not goes to responded. i want to read response

@ahuang4321
Copy link

same, I would like to get a response when I have an error? however at the moment it only shows the code which isn't that useful in accurately diagnosing what's wrong with the request I've sent.

@Jonarod
Copy link

Jonarod commented Jun 13, 2019

Same here, please reopen this issue.
Basically, the responded event is not always triggered. In case of error, it is just skipped (Android).

@Srikanthjava972
Copy link

@mshanak @davecoffin @developper89 @peterbsmyth @friedolinfoerder I still have same issue for android in case of api failure, I wanted to take the error json response from server but reponded & complete events are not triggered, can anyone please get back me with the solution, thanks in advance

@Srikanthjava972
Copy link

Srikanthjava972 commented Feb 1, 2022

@mshanak @davecoffin @developper89 @peterbsmyth @friedolinfoerder I have same issue, unable to handle the response coming from server with 400 status for andriod.

Here is my code

   `public multipartUpload(url: string, token: string, bgSessionName: string,
    params: any, androidNotificationTitle: string = 'Sync complete') {

    const session = bgHttp.session(bgSessionName);
    const name = 'test';
    const description = `${name} (${++this.counter})`;
    const request = {
        url: url,
        method: 'POST',
        headers: {
            Authorization: this.apiHelper.getAuthHeaderAsString(token),
            'Content-Disposition': 'form-data; name=' + name + 'filename=' + name,
            'Content-Type': 'application/octet-stream'

        },
        description: description,
        androidAutoDeleteAfterUpload: false,
        androidNotificationTitle: androidNotificationTitle,
        androidAutoClearNotification: true
    };

    setTimeout(() => { // Timeout of 20 seconds. If the upload doesn't complete in 20 seconds. it will return a 408.
        if (!this.finishedUploading) {
            this.response.next({responseCode: 408, data: 'Multipart upload timed out'});
        }
    }, 20000);

    const task = session.multipartUpload(params, request);
    this.bindTask(task);
    return this.response;
}

/**
 * Bind the task to the events. This will create callbacks for every stage of the call.
 * (responsed, progress, complete, error)
 *
 * To get the response code and data from the response, please subscribe on MultipartHandlerService.response
 *
 * @param task - bgHttp.Task
 */
private bindTask(task: bgHttp.Task): any {
    task.on('progress', this.onEvent.bind(this));
    task.on('error', this.onEvent.bind(this));
    task.on('responded', this.onEvent.bind(this));
    task.on('complete', this.onEvent.bind(this));
    this.lastEvent = '';
}

private onEvent(e): Observable<boolean> {
    if (this.lastEvent !== e.eventName) {
        // suppress all repeating progress events and only show the first one
        this.lastEvent = e.eventName;
    } else {
        return;
    }
    if ( e.eventName === 'complete') {
        console.log('completehandler')
        this.finishedUploading = true;
        this.response.next({responseCode: e.responseCode, data: JSON.parse(this.data)});
    }

    if ( e.eventName === 'responded') {
        console.log('respondhandler')
        this.data = e.data;
        console.log(e.data)
    }

    if ( e.eventName === 'error') {
        console.log(`Multipart HTTP error.
                    ResponseCode: ${e.responseCode},
                    Response: ${e.response}`);
    }

    this.events.push({
        eventTitle: e.eventName + ' ' + e.object.description,
        eventData: JSON.stringify({
            error: e.error ? e.error.toString() : e.error,
            currentBytes: e.currentBytes,
            totalBytes: e.totalBytes,
            body: e.data,
            responseCode: e.responseCode
        })
    });
}

}
`
Can anyone help me in fixing this where should I make my changes to handle the error response coming from server. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests