Angular HTTPClient POST body not sending - javascript

Currently I am trying to POST a name, email and message from an angular frontend to a php script running in the same nginx server which then runs phpmailer to send an email containing the name, email and message. Here is the code so far:
import { Component, OnInit } from '#angular/core';
import { Email } from './email';
import {ContactService} from './contact.service';
import {HttpClient, HttpHeaders} from '#angular/common/http';
import {NgForm} from '#angular/forms';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded'
})
};
const email = new Email('', '', '');
#Component({
selector: 'app-contact',
templateUrl: './contact.component.html',
styleUrls: ['./contact.component.css'],
providers: [ContactService]
})
export class ContactComponent implements OnInit {
email = new Email('', '', '');
constructor(private http: HttpClient) { }
sendEmail(form: NgForm) {
const value = form.value;
const senderName = value.name;
const senderEmail = value.email;
const senderMessage = value.message;
this.sendMail(senderName, senderEmail, senderMessage);
}
sendMail(senderName, senderEmail, senderMessage) {
console.log(senderName + ' ' + senderEmail + ' ' + senderMessage);
this.http.post('https://ruffstuffcostumes.tk/assets/scripts/email.php',
{
name: senderName,
email: senderEmail,
message: senderMessage,
},
httpOptions
)
.subscribe(
(val) => {
console.log('POST call successful value returned in body',
val);
},
response => {
console.log('POST call in error', response);
},
() => {
console.log('The POST observable is now completed.');
});
}
ngOnInit() {
}
}
When I ran the POST request through postman to check it, it ran perfectly well and sent out the email containing the required elements, however when I execute a query with this script, even though the console.log(senderName + ' ' + senderEmail + ' ' + senderMessage) does show the values, it doesn't seem to post them in the body at all, and all I get back is the fact that even though a mail was sent, it was sent without any of those values in the body of the email.
Could it be cross-origin problems (and if so what would be the best way to get around that?), or am I just doing some stupid mistake?

Just for completeness. I solved the problem by switching to sending JSON data and parsing it on the php side

Related

Saving data in angular 8 with subscribe [duplicate]

This question already has answers here:
How do I return the response from an Observable/http/async call in angular?
(10 answers)
Closed 3 years ago.
Hello I have a problem with saving data in subscribe with angular 8.
when i make this this.service.getAll().subscribe(response => console.log(this.itemList = response))
and print itemList the array is empty, i try to print the response in the subscribe and response have data.
I tried to make print in subscribe and print of local array in this way :
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { ItemService } from 'src/service/item.service';
import { Item } from 'src/DTO/item';
#Component({
selector: 'app-crafting-dashboard',
templateUrl: './crafting-dashboard.component.html',
styleUrls: ['./crafting-dashboard.component.css']
})
export class CraftingDashboardComponent implements OnInit{
itemList: Item[] = [];
constructor(private router: Router, protected service: ItemService) {
}
ngOnInit() {
this.service.getAll().subscribe(response => console.log("Reponse:" + response));
console.log("Constrol print" + this.itemList);
}
getAll(){
}
}
i've noted that in console appear first the console.log("Constrol print" + this.itemList);
and after the print of subscribe. It could be this the problem?!?!?
this is my service (i made an abstract service and in the specific service I add the specific method for an entity:
import { Service } from './service';
import { Observable } from 'rxjs';
import { HttpClient } from '#angular/common/http';
export class AbstractService<DTO> implements Service<DTO> {
type: string = '';
port: string = '8080';
constructor(protected http: HttpClient){}
getAll(): Observable<DTO[]> {
return this.http.get<DTO[]>('http://localhost:' + this.port + '/' + this.type + '/getAll');
}
read(id: number): Observable<DTO> {
return this.http.get<DTO>('http://localhost:' + this.port + '/' + this.type + '/read?id=' + id);
}
insert(dto: DTO): Observable<DTO> {
return this.http.post<DTO>('http://localhost:' + this.port + '/' + this.type + '/insert', dto);
}
update(dto: DTO): Observable<DTO> {
return this.http.put<DTO>('http://localhost:' + this.port + '/' + this.type + '/update', dto);
}
delete(id: number): Observable<any> {
return this.http.delete('http://localhost:' + this.port + '/' + this.type + '/delete?id=' + id);
}
}
The back-end is written in java with spring
In this code:
ngOnInit() {
this.service.getAll().subscribe(response => console.log("Reponse:" + response));
console.log("Constrol print" + this.itemList);
}
The callback response => console.log("Reponse:" + response) is delayed, it executes when receiving the HTTP response. This explains the behavior you observed ("Constrol print" being shown before "Reponse:").
If you have to do something with the data you receive, do it in the callback, and not in ngOnInit:
this.service.getAll().subscribe(response => {
console.log("Reponse:" + response);
//Whatever you want to do with the response and the variables assigned to the response goes here
});
Do like this
this.service.getAll().subscribe(response => {
this.itemList=response;
console.log("Console print" + this.itemList);
});

Working with HTTP-responses in angular2

I'm working on web-app with authorization via JWT and Angular 2. I've Nodejs/express server with API and client-side on Angular2.
So, my server answers GET request correctly and gives data like this:
{
"success": true,
"user": {
"_id": "5a6ef70edb04dd29e24bb03b",
"email": "danko",
"username": "ivan"
}
}
Next, here is my auth.service.ts. Functions createAuthenticationHeaders() and getProfile() takes part in handling HTTP responses:
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders, HttpRequest, HttpResponse, HttpParams} from '#angular/common/http';
import { Http, Headers, RequestOptions} from '#angular/http'; // Http, Headers, RequestOptions
import 'rxjs/add/operator/map';
#Injectable()
export class AuthService {
domain = "http://localhost:8080";
authToken;
user;
options;
constructor(
private http: HttpClient,
private httplegacy: Http) { }
createAuthenticationHeaders() {
this.loadToken();
this.options = new RequestOptions({
headers : new Headers({
'Content-Type' : 'application/json',
'authorization' : this.authToken
})
});
}
loadToken() {
this.authToken = localStorage.getItem('token');
}
registerUser(user) {
return this.http.post(this.domain + '/authentication/register', user);
}
loginUser(user) {
return this.http.post(this.domain + '/authentication/login', user);
}
storeUserData(token, user) {
localStorage.setItem('token', token);
localStorage.setItem('user', JSON.stringify(user));
this.authToken = token;
this.user = user;
}
getProfile() {
this.createAuthenticationHeaders();
return this.httplegacy.get(this.domain + '/authentication/profile', this.options);
}
}
Also, here is my profile.component.ts:
import { Component, OnInit } from '#angular/core';
import { AuthService} from '../../services/auth.service';
#Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
username;
email;
constructor(
private authService: AuthService
) { }
ngOnInit() {
this.authService.getProfile().subscribe(profile => {
console.log(profile);
this.username = profile.user.username;
this.email = profile.user.email;
})
}
}
Expected behavior of these lines of code: after handling server's response with user's data with auth.service.ts(mainly createAuthenticationHeaders() and getProfile() functions), user's data is transmitted to profile.component.ts to show it on web-page using next code:
<h2 class="page-header">Profile Page</h2>
<ul class="list-group">
<li class="list-group-item">Username: {{ username }} </li>
<li class="list-group-item">Email: {{ email }}</li>
</ul>
But, while compiling I got an error: property 'user', doesn't exist on type 'Response'. Would You like to explain why i got such error, and how to fix it?
P.S.: yep, console.log(profile) gives me such info:
Response {_body: "{"success":true,"user":{"_id":"5a6ef70edb04dd29e24bb03b","email":"danko","username":"ivan"}}", status: 200, ok: true, statusText: "OK", headers: Headers, …}
headers:Headers {_headers: Map(1), _normalizedNames: Map(1)}
ok : true
status : 200
statusText : "OK"
type : 2
url : "http://localhost:8080/authentication/profile"
_body : "{"success":true,"user":{"_id":"5a6ef70edb04dd29e24bb03b","email":"danko","username":"ivan"}}"
__proto__ : Body
constructor : ƒ Response(responseOptions)
toString : ƒ ()
__proto__ :
Object
But how can I get data from _body field of response?
P.S.: code for router from server side:
router.get('/profile', (req, res) => {
User.findOne({ _id: req.decoded.userId }).select('username email').exec((err, user) => {
if (err) {
res.json({ success: false, message: err });
} else {
if(!user) {
res.json({ success: false, message: 'User not found'});
} else{
res.json({ success: true, user: user });
}
}
});
});
you try to read your data directly from the Response Object of express. You need smth like:
this.authService.getProfile().subscribe(profile => {
console.log(profile);
let p = JSON.parse(profile._body)
this.username = p.user.username;
this.email = p.user.email;
})
This will take the JSON string from the body of your HTTP Response and make it an accessible object.
NOTE:
It would be much better to tell the server to answer with a standard json due to this is web standard nowadays.
Update: #messerbill's was 50/50 correct. Such construction works:
this.authService.getProfile().subscribe(profile => {
console.log(profile);
let p = JSON.parse(profile._body)
this.username = p.user.username;
this.email = p.user.email;
})
My web-page got user's info and show it in correctly, but an error left and i've to comment these lines of code to compile and run my application, and uncomment after to see user's info on webpage.
An error message: property '_body' does not exists on type 'Response'.
So, at this moment i've no idea how it works with an error and how to create really correct structure.
Try this
ngOnInit() {
this.authService.getProfile().subscribe(profile => {
console.log(profile);
let p = profile.json();
this.username = p.user.username;
this.email = p.user.email;
})
}

Angular 4 with mailgun

I am trying to make a simple email form for one of my websites that allows people to contact me. This site is using angular 4, and mailgun as the mail service. In my mail service file I have this method that sends the message, but I am getting a Bad Request error saying from is not present.
public sendMail(){
let url = 'https://api.mailgun.net/v3/XXXXXXXXXXXX.mailgun.org/messages';
let headers: Headers = new Headers();
headers.append('Authorization','Basic '+ btoa('api:key-XXXXXXXXXXXXXXXXXXX'));
headers.append("Content-Type", "application/x-www-form-urlencoded");
let opts: RequestOptions = new RequestOptions();
opts.headers = headers;
this.http.post(url,
{
from: '"Mailgun Sandbox" <postmaster#XXXXXXXXXX.mailgun.org>',
to: "Test <test#gmail.com>",
subject: 'Hello ',
text: 'Congratulations, you just sent an email with Mailgun! You are truly awesome!'
},
opts
).subscribe(
success => {
console.log("SUCCESS -> " + JSON.stringify(success));
}, error => {
console.log("ERROR -> " + JSON.stringify(error));
}
);
}
I am having a hard time understanding why from is showing up not as present when I send the request. Any help is great.
import { Injectable } from '#angular/core';
import { HttpHeaders, HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class PostService {
constructor(private http: HttpClient) {
}
sendMail() {
const headers = new HttpHeaders({
'enctype': 'multipart/form-data',
'Authorization': 'Basic ' + btoa('api:xxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxx-xxxxxx')
});
const formData = new FormData();
formData.append('from', 'Mailgun Sandbox <postmaster#sandboxxxxxxxxxxxxxx.mailgun.org>');
formData.append('to', 'xxxxxxxxxxxxxx.com');
formData.append('subject', 'Hello');
formData.append('text', 'This is cool !');
this.http
.post(
'https://api.mailgun.net/v3/sandboxxxxxxxxxxxxxxxxxxxxxxxxxxb.mailgun.org/messages',
formData,
{ headers }
).subscribe(
res => { console.log('res : ', res); },
err => { console.log('err : ', err); }
);
}
}

Nested Observables behaving differently in Ionic2/Angular2 App

I am creating an ionic login module, where in there are 2 observables , 1 inside another, Not sure if this is the correct way of implementation,
Here I am trying to call getHTTP() method, get a string, if the string is not empty then set it in ionic-storage varaible and then verify before logging in
Since Observables are async - getHTTP() is getting completed after the flow of login(credentials) , Help me out
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
import {Observable} from 'rxjs/Observable';
import {Headers} from '#angular/http';
import { Response } from '#angular/http';
import { Storage } from '#ionic/storage';
export class User {
name: string;
password: string;
url: string;
constructor(name: string, password: string, url: string) {
this.name = name;
this.password = password;
this.url = url;
}
}
/*
Generated class for the AuthService provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
#Injectable()
export class AuthService {
currentUser: User;
data = '';
constructor(public http: Http,private storage: Storage) {
console.log('Hello AuthService Provider');
}
// Make a call to Get CSRF and check if we have access
public getHTTP(credentials) {
let responseCSRF ;
const headers: Headers = new Headers();
headers.append('Authorization', 'Basic ' + btoa(credentials.user + ':' + credentials.password));
headers.append('Content-Type', 'application/json');
console.log(headers);
console.log('Clearing cache');
this.storage.set('CSRF', '');
this.storage.set('Auth',btoa(credentials.user + ':' + credentials.password));
this.storage.set('url', credentials.url);
//return
responseCSRF = this.http.get('http://' + credentials.url +'/Windchill/servlet/rest/security/csrf', {
headers: headers
}).map((response: Response) => response.json());
//console.log(typeof(responseCSRF))
responseCSRF.subscribe(x => {
console.log('CSRF ->' + x.items[0].attributes.nonce)
this.data = x.items[0].attributes.nonce;
if(typeof this.data!='undefined' && this.data) {
this.storage.set('CSRF', this.data);
}
});
return responseCSRF;
}
public login(credentials) {
if (credentials.user === null || credentials.password === null || credentials.url === null ) {
return Observable.throw("Please insert credentials ");
} else {
return Observable.create(observer => {
// At this point make a request to your backend to make a real check!
let access = false;
this.getHTTP(credentials).subscribe (
(resBody) => console.log('Boby is '+resBody),
error => console.error('Error from auth-service: ' + error))
, () => console.log('Completed!' + 'Auth' );
this.storage.get('CSRF').then((val) => {
console.log('Your CSRF is'+ val);
if(val!='undefined') {
access = true;
}
});
observer.next(access);
observer.complete();
});
}
}
public getUserInfo() : User {
return this.currentUser;
}
public logout() {
return Observable.create(observer => {
this.currentUser = null;
observer.next(true);
observer.complete();
});
}
}
In the Console
Headers {_headers: Map(2), _normalizedNames: Map(2)}
auth-service.ts:49 Clearing cache
auth-service.ts:57 pluck -->[object Object]
auth-service.ts:83 Your CSRF is
auth-service.ts:59 CSRF ->RkPYp+UtGGMRB+8NJHCr9rJ6WhBHdIVCfim585xXKgZ1TKUmf3v39tBqVRkjSb93dgWi4oF3KF4rNts0c3frktUdIFokNNVrMSGM47V3KwQhP8A5ARKr5rBsaxtmOtI=
auth-service.ts:78 Boby is [object Object]
Try to put your storage.get logic inside subscription handler:
return Observable.create(observer => {
// At this point make a request to your backend to make a real check!
let access = false;
this.getHTTP(credentials).subscribe(
(resBody) => {
console.log('Boby is ' + resBody);
this.storage.get('CSRF').then((val) => {
console.log('Your CSRF is' + val);
if (val != 'undefined') {
access = true;
}
observer.next(access);
observer.complete();
});
},
error => console.error('Error from auth-service: ' + error),
() => console.log('Completed!' + 'Auth'));
});

How to pass objects between server side node and client side angular 2? [duplicate]

How to make AJAX call with angular2(ts)?
I read the tutorial on angularjs.org. But there is nothing about AJAX.
So I really want to know how to make AJAX call with angular2(ts).
You will want to look at the api docs for the http module. The http class can get resources for you using AJAX. See the Angular HttpClient Guide for more examples.
import { Component } from '#angular/core';
import { Http } from '#angular/http';
#Component({
selector: 'http-app',
templateUrl: 'people.html'
})
class PeopleComponent {
constructor(http: Http) {
http.get('people.json')
// Call map on the response observable to get the parsed people object
.map(res => res.json())
// Subscribe to the observable to get the parsed people object and attach it to the
// component
.subscribe(people => this.people = people);
}
}
import { Component, OnInit } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { Http, Response, Headers, RequestOptions } from '#angular/http';
import 'rxjs/add/operator/map';
#Component({
selector: 'dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css'],
providers: [RemoteService]
})
export class DashboardComponent implements OnInit {
allData = [];
resu: string;
errData: string;
name: string = "Deepak";
constructor(private http: Http){}
ngOnInit(){}
onSubmit(value: any) {
//console.log(value.message);
let headers = new Headers({ 'Content-Type': 'application/json'});
let options = new RequestOptions({ headers: headers });
let body = JSON.stringify(value);
this.http.post('127.0.0.1/myProject/insertData.php', body, headers)
.subscribe(
() => {alert("Success")}, //For Success Response
err => {console.error(err)} //For Error Response
);
}
}
json-data.service.ts
import { Injectable } from '#angular/core';
import { Http, Response, RequestOptions, Headers } from "#angular/http";
import 'rxjs/add/operator/map';
import { Observable } from 'rxjs/Observable';
#Injectable()
export class JsonDataService {
errorMessage: any;
constructor(private http: Http) {
}
getData(): Observable<JsonData[]> {
console.log('Retriving Data from Server.......');
return this.http.get('http://883.82.3:8086/restfullDataApi/UserService/jsondata')
.map(this.extractData)
.catch(this.handleError);
}
getSolrData() {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
let url = "http://883.8.2:8086/PI3_Solr_WebService/solrService"; /
return this.http.post(url).map((res: Response) => res.json());
}
let body = res.json();
return body || [];
}
private handleError(error: any) {
// In a real world app, we might use a remote logging infrastructure
// We'd also dig deeper into the error to get a better message
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg); // log to console instead
alert("Server Error!");
return Observable.throw(errMsg);
}
AJAX is fully transparent in angularjs, see the links and examples below.
https://docs.angularjs.org/api/ng/service/$http
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
https://docs.angularjs.org/api/ngResource/service/$resource
var User = $resource('/user/:userId', {userId:'#id'});
User.get({userId:123}, function(user) {
user.abc = true;
user.$save();
});

Categories

Resources