Property 'blob' does not exist on type 'HttpResponse<any>' - angular5

i am trying to upgrade angular 4 to 5 and for that i had to import HttpClient, HttpResponse , HttpHeaders from #angular/common/http instead of importing Http, Response, Headers, RequestOptions, ResponseContentType from '#angular/http';
but in my code earlier i was using let headers = new Headers(); which i replaced with let headers = new HttpHeaders(); and responseType: ResponseContentType.Blob replaced with responseType: 'blob'
now in method getData() res.blob() says Property 'blob' does not exist on type 'HttpResponse'.
ExcelDownload(_getRequestUrl: string) {
let headers = new HttpHeaders();
headers.append('Content-Type', 'application/json' );
return this.http.get(this.getUrlWithEmpId(_getRequestUrl), {
headers : headers,
responseType: 'blob'
}).map(response => this.getData(response)) .catch(error => this.handleError(error));
}
public getData(res: HttpResponse<any>) {
let headers = res.headers;
let contentType = headers.get('Content-Type');
var blob;
try {
if(contentType === 'pdf' || contentType === 'application/pdf') {
//chek this
blob = new Blob([res.blob()], { type: "application/pdf"});
} else {
//check thi
blob = new Blob([res.blob()], { type: "application/vnd.ms-excel"});
}
}
catch (e) {
}
return blob;
}

Related

How to set formData for boolean in Axios post request

I'm trying send a post request using axios to my backend but I can't send the boolean "isActive" for some reason. Is there a way to do this?
async submit() {
const isValid = await this.$validator.validateAll()
if (isValid && !this.submitting) {
let formData = new FormData();
formData.set("city", this.formData.city)
formData.set("state", this.formData.state)
formData.set("county", this.formData.county)
formData.set("isActive", true) // <- NOT ACCEPTING THIS VALUE
axios.post("/api/v1/team/createTeam", formData, {
headers: {
'Content-Type': 'application/json'
}
})
.then(res => {
if (res.status === 200) {
this.submitting = true
this.cancelModal()
} else {
console.log(res.data.code);
}
})
.catch(function (err) {
console.log(err);
})
}
}
FormData can only contain string values. Setting a Boolean true would result in "true" for the value. The backend would have to convert that string to a Boolean.
Also, your header should not be application/json (intended for JSON payloads). If sending FormData as the payload, the header should be multipart/form-data:
axios.post("/api/v1/team/createTeam", formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
If your backend is actually expecting JSON, then you can't send FormData. Switch to a JavaScript object instead (which does accept Booleans):
const payload = {
city: this.formData.city,
state: this.formData.state,
county: this.formData.county,
isActive: true,
}
axios.post("/api/v1/team/createTeam", payload, {
headers: {
'Content-Type': 'application/json'
}
})

In Nodejs/Express js i am unable to return response to Angular 6

I am using Angular 6 and Nodejs/Expressjs to avoid cross domain issue. So here is my code
In Angular i am calling:
this.httpClient.post('/uploadFile', formData, {params: params})
.pipe(map((res: any) => {return res}),
catchError((error: HttpErrorResponse) => {})
Nodejs/Expressjs:
app.post('/uploadFile', (req, res) => {
let formData
const form = new IncomingForm();
let readStream;
form.on('file', (field, file) => {
console.log('file.path>>>',file.path);
readStream = fs.createReadStream(file.path);
});
form.on ('fileBegin', function(name, file) {
//rename the incoming file to the file's name
let fileName = file.path.split("\\");
fileName[fileName.length-1] = file.name.split('.')[0];
fileName = fileName.join("\\");
file.path = fileName;
console.log('file.path', file.path);
console.log('file.name', file.name);
})
form.parse(req, function (err, fields, files) {
formData = new FormData();
formData.append("file", readStream);
formData.append('package_name', req.query.packagename);
formData.append('type', req.query.type);
formData.append('version', req.query.version);
formData.append('descr', req.query.descr);
console.log('req.query.packagename',req.query.packagename);
const axiosConfig = {
headers: {
'Content-Type': 'multipart/form-data'
}
};
let uploadRequest = request.post("WebAPiCallURL", requestCallback);
uploadRequest._form = formData;
uploadRequest.setHeader('Content-Type', 'multipart/form-data');
function requestCallback(err, res, body) {
return JSON.parse(body);
}
});
});
From requestCallback i am unable to send response to Angular6
Your not sending response from to the client. To send you can use res.send or any of the response function from Expressjs.
function requestCallback(err, response, body) { //Rename res to response to avoid conflict
res.send(body); // Send Response to Client
}
Note : As you used same variable res for request, Rename to some other name

Api call is not happening while calling Http Request using HttpClient in angular 7

I am converting a post API request written in javascript to typescript, but my new code seems to be not running as i do not see any network calls in the debugger. Please find my code snippets below.
javascript (working)
private resourcesAccessable(url, token, clientId, resources) {
var request = new XMLHttpRequest();
request.open('POST', url, false);
request.setRequestHeader("Authorization", "Bearer " + token);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
console.log(request);
var response ;
request.onreadystatechange = function () {
if (request.readyState == 4) {
var status = request.status;
if (status >= 200 && status < 300) {
response = JSON.parse(request.responseText);
} else if (status == 403) {
console.log('Authorization request was denied by the server.');
return null;
} else {
console.log('Could not obtain authorization data from server.');
return null;
}
}
}
var params = "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket&response_mode=permissions&audience="+clientId;
if(Array.isArray(resources)){
for (var i = 0; i < resources.length; i++) {
params = params+"&permission="+resources[i]
}
}
request.send(params);
console.log(response);
return response;
}
typescript (not working)
resourcesAccessable(url, token, clientId, resources) {
private http: HttpClient,
private payload
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + token
})
};
this.payload = new URLSearchParams();
this.payload.set('grant_type','urn:ietf:params:oauth:grant-type:uma-ticket');
this.payload.set('response_mode','permissions');
this.payload.set('audience', clientId);
this.payload.set('permission',resources);
return this.http.post(url, payload.toString(), httpOptions)
.pipe(
tap(
(data) => {
console.log('----->>>', data);
}
)
), error => {
console.log('error ' + JSON.stringify(error));
};
}
I have tried many things to run the above code but none of them worked for me.
Split your code into the following sections. Angular/RxJS is different from vanilla JavaScript. You create Observable http calls which the Subscriber then reads from.
Inject HttpClient into your class -- necessary for http calls to work. (Needs additional dependencies to work. Please refer https://angular.io/guide/http)
constructor(protected http: HttpClient) {}
Function Definition
resourcesAccessable(url, token, clientId, resources): Observable<any> {
const payload = new URLSearchParams()
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + token
})
}
payload.set('grant_type', 'urn:ietf:params:oauth:grant-type:uma-ticket')
payload.set('response_mode', 'permissions')
payload.set('audience', clientId)
payload.set('permission', resources)
return this.http.post(url, payload.toString(), httpOptions)
}
Function Call
this.resourcesAccessable('', '', '', '')
.subscribe(
(data) => {
console.log('----->>>', data);
}
, error => {
console.log('error ' + JSON.stringify(error));
},
() => console.log('Completed'));

save jpg image in s3 with signed URL

I am using a signed URL returned by AWS Lambda to upload an jpg image with Angular HTTPClient to S3 bucket. I can see the image.jpg file but when I open it, it says it is invalid format. Please help!
I am expecting I need these HTTP request headers:
'Content-Type': 'image/jpeg'
'Content-Encoding': 'base64'
and I tried with and without the
"data:image/jpeg;base64,"
followed by the based64 encoded data as string.
My lambda is:
var AWS = require('aws-sdk');
var s3 = new AWS.S3({
signatureVersion: 'v4',
});
exports.handler = (event, context, callback) => {
const url = s3.getSignedUrl('putObject', {
Bucket: 'landlord-bucket',
Key: 'image' + '.jpg',
Expires: 20,
ContentEncoding: 'base64',
ContentType: 'image/jpeg',
});
callback(null, url);
};
I upload it using:
#Effect() postToS3$: Observable<Action> = this.actions$
.ofType(PropertyActions.UPLOAD_FILE_PUTS3)
.switchMap((action: PropertyActions.UploadFilePutS3) => {
return this.httpClient.put(action.payload, "data:image/jpeg;base64," + this.filesToUpload)
.pipe(map(res => {
return new PropertyActions.OpenAllProperties(res);},
err => {
console.log("Error occured in get signed url");
}))
})
this.filesToUpload is the string of the base64 encoded jpg. This is correctly encoded since I can see the image at any decoder site.
HTTP interceptor is:
#Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private authService: AuthService) {}
intercept (req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.authService.getAuthenticatedUser().getSession((err, session) => {
if (err) {
console.log("Error getSession")
return next.handle(req);
}
let authReq = null;
if (req.url.indexOf('X-Amz-Algorithm') === -1) {
authReq = req.clone({
headers: req.headers.set('Authorization', session.getIdToken().getJwtToken())
});
} else {
authReq = req.clone({
setHeaders: {'Content-Type': 'image/jpeg', 'Content-Encoding': 'base64'}
});
}
return next.handle(authReq);
})
}
}

Angular 2 RC 5 Attempting to Get and Display a PDF from a Server

I am trying to display a PDF that is generated from a server onto a view in my Angular 2 RC 5 project. Right now, the ASPNETCORE server is returning the object as an 'application/pdf' and the Angular client is trying to parse the response as a blob. However, I get the following error on the client side:
Error: The request body isn't either a blob or an array buffer
The code that I'm using to call the PDF server is essentially:
getHeaders() : Headers {
var headers = new Headers({
'responseType': 'application/blob'
});
return headers;
}
getBlob() {
return this.http.get(uri, new RequestOptions({headers: this.getHeaders()}, body: "" }))
.map(response => (<Response>response).blob());
}
Try to set the responseType to Blob, it should work:
getBlob() {
return this.http.get(uri, {responseType: ResponseContentType.Blob})
.map(response => (<Response>response).blob());
}
Work's for me :
Component :
downloadInvoice(invoice) {
this.loading = true;
this.invoiceDataService
.downloadInvoice(invoice)
.subscribe(
(blob) => {
FileSaver.saveAs(blob, 'test.pdf');
},
error => this.error = error,
() => {
this.loading = false;
console.log('downloadInvoices : Request Complete')
}
)
}
Data service :
downloadInvoice(invoice): Observable<Blob> {
return this.api.downloadInvoice(invoice);
}
Api service :
downloadInvoice(invoice: Invoice): Observable<Blob> {
return this.authHttp
.get(this.apiBase + '/invoices/' + invoice.hashid + '/download', {responseType: ResponseContentType.Blob})
.map(response => {
return new Blob([response.blob()], {type: 'application/pdf'});
})
.catch(this.handleError.bind(this));
}
Enjoy :)
For Angular 5, ResponseContentType has been deprecated, so a current solution I found was to use:
getFile(): Observable<File> {
let options = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
responseType: 'blob' as 'json'
};
return this.http.get<File>(uri, options);
}