Reputation: 1045
I have an Angular app with a simple call to a service to upload an image to AWS S3. The upload service should return the AWS response to the caller. Despite the upload service successfully uploading the file and throwing the success message to the console, and despite a RETURN of the promise resolved, the caller "then" is not kickin in. There is no error messsage, only the following console.log statement is ignored:
console.log('aws file returned: ', res);
Here is the caller:
this.aws.uploadDataFile(data).then(res => {
if (res) {
console.log('aws file returned: ', res);
}
}, err => {
console.log('error: ', err);
});
Here is the upload service called:
uploadDataFile(data: any){
const contentType = data.type;
const bucket = new S3({
accessKeyId: environment.awsAccessKey,
secretAccessKey: environment.awsSecret,
region: environment.awsRegion
});
const params = {
Bucket: environment.awsBucket,
Key: data.name, //manipulate filename here before uploading
Body: data.value,
ContentEncoding: 'base64',
ContentType: contentType
};
return new Promise(function(resolve,reject){
bucket.putObject(params, function(err, res) {
if (err) {
console.log(err);
console.log('Error uploading data: ', res);
return Promise.resolve(err);
}
console.log('succesfully uploaded the image! ' + JSON.stringify(res));
return Promise.resolve(res);
});
})
}
I do see the success message from the service in the console:
console.log('succesfully uploaded the image! ' + JSON.stringify(res));
But this message is not showing:
console.log('aws file returned: ', res);
I need the returned value in the caller to further perform tasks. What am I missing?
Upvotes: 0
Views: 563
Reputation: 46
The Promise
you are creating has an executor
callback that provides the resolve
and reject
methods you should use to resolve the promise. Additionally, any return values from your executor
are ignored. You can't chain onto the promise by returning a promise in the executor
. This is documented on MDN for the Promise constructor.
The main issue is that you are not using the executor
parameters to resolve or reject the promise. This leaves your promise in a pending state indefinitely. Invoking the appropriate resolve
or reject
will fix the issue.
function uploadDataFile(data) {
//...
return new Promise(function(resolve, reject) {
bucket.putObject(params, function(err, res) {
if (err) {
console.log(err);
console.log('Error uploading data: ', res);
reject(err);
} else {
console.log('succesfully uploaded the image! ' + JSON.stringify(res));
resolve(res);
}
});
});
}
In your case you are using the AWS
API. So, you could use the built-in promise
method from AWS
. The promise
method does the same conversion as above.
function uploadDataFile(data) {
//...
return bucket.putObject(params).promise().then(function(res) {
console.log('succesfully uploaded the image! ' + JSON.stringify(res));
return res;
}).catch(function(err) {
console.log('Error uploading data: ');
console.log(err);
throw err;
});
}
If you do not need the extra logging you can just return the promise.
function uploadDataFile(data) {
//...
return bucket.putObject(params).promise();
}
Upvotes: 2
Reputation: 944246
You're resolving the wrong promise.
Promise.resolve
is a function which creates a new promise and immediately resolves it. It is extremely rare that it is actually useful.
It is not the same as the function which is passed by the Promise
constructor function to your callback and placed in the first argument which you have named resolve
.
You need to resolve that promise and not a new one.
Note that the AWS API has built-in support for promises so you don't need to promisify the callback function yourself anyway.
Upvotes: 1