I have seen several other questions like this, but they do not solve the issue. I used MailChimp's API to make a simple call to add a member to my mailing list when they sign up.
However when I test, I get a 401 unauthorized and the API complains of no API key submitted. When I inspect the request in Chrome, I don't see any Authorization header. Here is my code:
const formData = {
email_address: this.emailControl.value,
status: 'subscribed',
merge_fields: {
NAME: this.nameControl.value
}
};
const header = new HttpHeaders({
'Authorization': 'apikey:' + environment.mailChimpApiKey
});
this.http.post(this.mailChimpUrl, formData, {
headers: header,
observe: 'response'
}).subscribe(response => {
console.log('response', response);
if (response.status === 200) {
this.submitted = true;
}
});
I have checked and double-checked the HttpClient.post method signature, and how the MailChimp API expects to receive the Auth header. It seems like I'm doing everything right, so why isn't Angular setting the header?
I am noticing that the value changes only for the Access-Control-Request-Headers
when I set optional headers. Am I reading the chrome console wrong?
Angular version: 5.2.4
The issue is not with Angular. Modern browsers send a preflight OPTIONS request for most cross-domain requests, which is not supported by Mailchimp. The Mailchimp API does not support client-side implementations:
MailChimp does not support client-side implementation of our API using CORS requests due to the potential security risk of exposing account API keys.
It would have been nice if this was stated a bit more obviously, but I didn't notice it at first. The best solution is to use jsonp.
To do this we need to import Headers
and RequestOptions
along with Http
from @angular/http
library.
And as @Maciej suggested you can also use withCredentials : true
to your request options.
ApplicationService.ts
import { Injectable } from '@angular/core';
import { Http, Headers, Response, RequestOptions } from '@angular/http';
@Injectable()
export class ApplicationService {
constructor(private http: Http) {
}
myformPost(id:number, formData : any){
let header = this.initHeaders();
let options = new RequestOptions({ headers: header, method: 'post'});
let body = JSON.stringify(formData);
return this.http.post(this.myapiUrl, body, options)
.map(res => {
return res.json();
})
.catch(this.handleError.bind(this));
}
private initHeaders(): Headers {
var headers = new Headers();
let token = localstorage.getItem(StorageKey.USER_TOKEN);
if (token !== null) {
headers.append('Authorization', token);
}
headers.append('Pragma', 'no-cache');
headers.append('Content-Type', 'application/json');
headers.append('Access-Control-Allow-Origin', '*');
return headers;
}
private handleError(error: any): Observable<any> {
return Observable.throw(error.message || error);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With