Reputation: 7054
I'm getting this error:
accounts.service.ts?29fe:45 SyntaxError: Unexpected end of JSON input. it's like the server don't like json format.
when i use Postman to send with x-www-form_urlencoded the two fields: lastname and firstname is working well.
I don't understand well the conversion that i must to do to work right with the backend, there is backend with x-www-form_urlencoded and another with full json? because most of tutorials dont'use any sort of conversion to send post data from the form. i've seen some solutiosn using new URLSearchParams(); but there nothing automatic in angular2 to do the conversion?
From my server log when i send the post with Postman i get:
add: {"lastname":"mylast","firstname":"myfirst"}
but with angular2 component i get:
add: {}
the data is not arriving
I have this component:
import {Component, Input, OnInit} from '@angular/core';
import {AccountsService} from '../shared/index';
@Component({
selector: 'app-accounts-form',
templateUrl: 'accounts-form.component.html',
styles: [require('./accounts-form.component.scss')],
providers: [AccountsService]
})
export class AccountsFormComponent implements OnInit {
@Input() accountId: string = '';
public account: any = {
firstname: '',
lastname: ''
};
constructor(private accountsService: AccountsService ) {
}
ngOnInit() {
if (this.accountId !='' ) {
this.getById();
}
}
onSubmit() {
if (this.accountId =='' ) {
console.log('submit new');
this.accountsService
.insert(this.account)
.subscribe((data) => {
console.log(data);
this.account = data
},
error => console.log(this.account),
() => console.log('Insert complete'));
} else {
console.log('submit update '+this.accountId);
}
}
private getById(): void {
this.accountsService
.getById(this.accountId)
.subscribe((data) => {
console.log(data);
this.account = data
},
error => console.log(this.account),
() => console.log('Get Item complete'));
}
}
the template:
<form (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="lastname">Last Name</label>
<input [(ngModel)]="account.lastname" name="lastname"/>
</div>
<div class="form-group">
<label for="firstname">First Name</label>
<input [(ngModel)]="account.firstname" name="firstname"/>
</div>
<div>
<button type="submit" class="btn btn-default"
>Submit</button>
</div>
</form>
the service:
import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import 'rxjs/add/operator/map'
import { Observable } from 'rxjs';
import { Configuration } from '../../app.constants';
@Injectable()
export class AccountsService {
private actionUrl: string;
private headers: Headers;
constructor(private http: Http, private configuration: Configuration) {
this.actionUrl = configuration.ServerWithApiUrl + 'accounts';
this.headers = new Headers();
this.headers.append('Content-Type', 'application/json');
this.headers.append('Accept', 'application/json');
}
public insert(body: any): Observable<any> {
console.log( 'insert url:'+ this.actionUrl );
console.log(JSON.stringify( body))
return this.http.post(this.actionUrl , JSON.stringify( body), { headers: this.headers })
.map((response: Response) => response.json())
.catch(this.handleError);
}
private handleError(error: Response) {
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
my backend server with mongo and express4:
const insert = function (req, res) {
data = req.body;
console.log('add: ' + JSON.stringify(data));
objectDb.insertOne(data, function (err, result) {
if (err) {
res.send({'error': 'An error has occurred'});
} else {
res.send(result[0]);
}
});
};
i've tried on my service don't use form value but hardcode values with & and json value , and does not work:
try send data with &
return this.http.post(this.actionUrl , 'firstname&=test1&lastname=test2', { headers: this.headers }) .map((response: Response) => response) .catch(this.handleError);
try send data with json
return this.http.post(this.actionUrl , {'firstname':'test1','lastname':'test2'}, { headers: this.headers })
.map((response: Response) => response)
.catch(this.handleError);
boths methods does not work
UPDATE:
I've changed insert() my service:
.map((response: Response) => response.json()) <-- removed .json() here;
have no more the error: 'Unexpected end of JSON input' just data is not sent to the server.
i've update to get the log of response:
.map((response: Response) => console.log(response))
then i get the new error:
core.umd.js?e2a5:2837 EXCEPTION: Error in ./AccountsFormComponent class AccountsFormComponent - inline template:3:9 caused by: Cannot read property 'lastname' of undefinedErrorHandler.handleError
actual updated insert() function in service code:
public insert(body: any): Observable<any> {
console.log( 'insert url:'+ this.actionUrl );
console.log(JSON.stringify( body))
return this.http.post(this.actionUrl , {'firstname':'test1','lastname':'test2'}, { headers: this.headers })
.map((response: Response) => console.log(response))
.catch(this.handleError);
}
on developper tool xhr tab i get:
Request URL:http://localhost:3000/accounts
Request Method:POST
Status Code:200 OK
Remote Address:[::1]:3000
Response Headers
view source
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Length:0
Date:Thu, 01 Dec 2016 14:21:04 GMT
X-Powered-By:Express
Request Headers
view source
Accept:application/json
Accept-Encoding:gzip, deflate, br
Accept-Language:de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4,fr;q=0.2
Connection:keep-alive
Content-Length:40
Content-Type:application/json
Host:localhost:3000
Origin:http://localhost:8080
Referer:http://localhost:8080/accounts-add
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36
Request Payload
view source
{firstname: "test1", lastname: "test2"}
firstname
:
"test1"
lastname
:
"test2"
Upvotes: 0
Views: 6532
Reputation: 16917
You are trying to post your body as 'application/json'
..
So do NOT JSON.stringify()
your body.
Upvotes: 2