Angular 2/4 how to POST JSON data made by Form - forms

I'm using FormBuilder for make JSON data,
I have made this form using FormBuilder, FormGroup, Validators, FormControl
this is my forms code
<form [formGroup]="SearchForm" (ngSubmit)="search(SearchForm.value)" name="SearchForms">
<input type="text" formControlName="checkin" value="12:00" placeholder="12:00" readonly> In
<input type="text" formControlName="checkout" value="10:00" placeholder="10:00" readonly> Out
<input type="text" formControlName="guest"> Guest
<input type="text" formControlName="room"> Room
<select formControlName="position">
<option value="sky">sky</option>
<option value="earth">Earth</option>
</select>
<input type="hidden" formControlName="date" name="date" value="{{selected_date}}">
<input type="hidden" formControlName="location" name="location" value="{{location}}">
<button class="btn shadow" type="submit"> Search </button>
</form>
and this my component.ts file
export class HomeComponent implements OnInit {
http: any;
SearchForm : FormGroup;
post:any;
location: string ='';
date:string = '';
checkin:string='';
checkout:string='';
guest:number;
room:number;
position:string='';
constructor(private fb: FormBuilder)
{
this.SearchForm = fb.group({
'location' : [null],
'date' : [null],
'checkin' : [null],
'checkout' : [null],
'guest' : [null],
'room' : [null],
'position' : [null],
});
}
search(post)
{
this.location = post.location;
this.date = post.date;
this.checkin = post.checkin;
this.checkout = post.checkout;
this.guest = post.guest;
this.room = post.room;
this.position = post.position;
this.http.post('http://localhost:4200/searchrequest',JSON.stringify(this.SearchForm))
}
ngOnInit()
{
this.SearchForm = new FormGroup(
{
location: new FormControl(),
date: new FormControl(),
checkin: new FormControl(),
checkout: new FormControl(),
guest: new FormControl(),
room: new FormControl(),
position:new FormControl()
});}
I have no idea what I should fo next for post data from SearchForm I have made.
Any help form my project? if someone has a link for example you can share it here.
Thanks before

search(post)
{
this.location = post.location;
this.date = post.date;
this.checkin = post.checkin;
this.checkout = post.checkout;
this.guest = post.guest;
this.room = post.room;
this.position = post.position;
this.http.post('http://localhost:4200/searchrequest',JSON.stringify(this.SearchForm))
}
should be
search(post)
{
this.http.post('http://localhost:4200/searchrequest',JSON.stringify(post))
}
you are currently assigning all the form values to the component Instance members when you can just as easily send the entire form value.
and you also initialize the searchForm twice, once with the FormBuilder service and the other time with a new FormGroup instance, which are doing exactly the same thing. you can remove the entire ngOnInit() function since you do it already in the constructor.
angular 5 FormBuilder doc's: https://angular.io/api/forms/FormBuilder
adding #marcidius comment as its a valuable part of the solution.
To fix that error you need to add a private http member to your
constructor: constructor(private fb: FormBuilder, private http: Http)
Also, in your example you don't even need to be passing the SearchForm
to that function since it is a class member already. Reactive Forms`
values are updated via their bindings so any update to the form
elements updates the model automatically. Just call this.searchForm in
the JSON.stringify(...) but don't worry about passing it into the
function.

I needed to get my this.contactForm.value in order to get the object of values . Than i did the stringify

Related

REACT Multiple Registration

I have a problem with React, so I created script and it doesn't work.
This should:
Render first state step (it's working) (Component First)
Here is error, it don't see default values.(name & email
After click Save And Continue it should save files to data.
And going to next steps in cases.
The error is
bundle.js:34147 Uncaught ReferenceError: email is not defined
function send(e){
e.preventDefault()
}
function nextStep(){
this.setState({
step:this.state.step + 1
})
}
function nextStep(){
this.setState({
step:this.state.step - 1
})
}
function saveAndContinue(e) {
e.preventDefault()
// Get values via this.refs
var data = {
name : this.refs.name.getDOMNode().value,
email : this.refs.email.getDOMNode().value,
}
this.props.saveValues(data)
this.props.nextStep()
};
var fieldValues = [
name : null,
email : null,
];
function saveValues(fields) {
return (
fieldValues = Object.assign({}, fieldValues, fields)
);
}
class Registration extends React.Component{
constructor () {
super()
this.state = {
step:1
}
}
render() {
switch (this.state.step) {
case 1:
return <First fieldValues={fieldValues}
nextStep={this.nextStep}
previousStep={this.previousStep}
saveValues={this.saveValues} />
case 2:
return <Two fieldValues={fieldValues}
nextStep={this.nextStep}
previousStep={this.previousStep}
saveValues={this.saveValues}/>
case 3:
return <Third fieldValues={fieldValues}
nextStep={this.nextStep}
previousStep={this.previousStep}
saveValues={this.saveValues}/>
case 4:
return <Success fieldValues={fieldValues} />
}
}
}
class First extends React.Component{
render(){
return(
<form onSubmit ={send}>
<div className="group">
<input className="text" type="text" ref="name" defaultValue={this.props.fieldValues.name}/>
<span className="highlight"></span>
<span className="bar"></span>
<label>Write Name</label>
</div>
<div className="group">
<input className="text" type="email" ref="email" defaultValue={this.props.fieldValues.email} />
<span className="highlight"></span>
<span className="bar"></span>
<label>Write Your Mail</label>
</div>
<button onClick={this.saveAndContinue}>Save and Continue</button>
</form>
)
}
}
There is no Two, Third and Success classes in your code, so I'm assuming they are similar to the First class.
A global function doesn't need this keyword. But in this case, you have to put saveAndContinue inside First class if it need to access the state.
In React, normally you don't have to set default value for input.
Link the input value to the state, and then setState in onChange event.
The string in placeholder is shown when the state is empty.
The code below shows how to work with input tag in React:
<input
value={this.state.inputValue}
onChange={e => {
this.setState({ inputValue: e.target.value });
}}
type="text"
placeholder="default value"
/>
Note that the state will updates onChange rather than click the save button.
Does this solve your problem?

Properties won't update on input change

I'm trying to adapt a working form I found for polymer 1.0 in order to work on polymer 2.0 but these two way data bindings don't seem to work.
My template:
<paper-input>
<label>Username</label>
<iron-input bind-value={{formData.username}}><input id="username" type="text" value="{{formData::input}}"></iron-input>
</paper-input>
<paper-input>
<label>Password</label>
<iron-input bind-value={{formData.password}}><input id="password" type="password" value="{{formData::input}}"></iron-input>
</paper-input>
<div class="wrapper-btns">
<paper-button raised class="primary" on-tap="postLogin">Log In</paper-button>
<paper-button class="link" on-tap="postRegister">Sign Up</paper-button>
</div>
My actions:
class MyLogin extends Polymer.Element {
static get is() { return 'my-login'; }
static get properties() {
return {
storedUser: Object,
error: String,
formData: {
type: Object,
value: {},
},
}
}
_setReqBody() {
console.log(this.formData) // <--- THIS LINE!
this.$.registerLoginAjax.body = this.formData;
}
postLogin() {
this.$.registerLoginAjax.url = 'http://localhost:3001/sessions/create';
this._setReqBody();
this.$.registerLoginAjax.generateRequest();
}
}
The indicate line will always print undefined though. What am I doing wrong?
Here's the full code: https://github.com/lpfjustino/PolymerQuickstart/blob/master/web/src/my-login.html
And here's the code mine is based on:
https://auth0.com/blog/build-your-first-app-with-polymer-and-web-components/
paper-input doesn't need any label nor iron-input inside it by default. That only goes for paper-input-container. So the following would be okay
<paper-input label="Username" value="{{formData.username}}"></paper-input>
However if you insist on using paper-input-container instead, then
<paper-input-container>
<label slot="label">Username</label>
<iron-input bind-value="{{formData.username}}" slot="input">
<!-- You don't need to add two-way binding for your input element here
since `iron-input` already handles that for you using its `bind-value`
attribute. -->
<input />
</iron-input>
</paper-input-container>
Also, when you declare an Object property, you should initialize it using a function to insure that each element instance would have its own copy of the property.
static get properties() {
return {
...
formData: {
type: Object,
value: function() {
return {}; // or return { username: '', password: '' }
},
},
};
}

ControlValueAccessor with FormArray in Angular 2

I have a child component which deals with the array of input controls. I want to have a formcontrol over the child component.
I am passing the array of json object, what would be the correct way to bind parent form to the child component's FormArray having 2 form control with Validator required on first.
This is the initial code
<h1>Child</h1>
<div formArrayName="names">
<div *ngFor="let c of names.control">
<input formControlName="firstName">
<input formControlName="lastName">
</div>
</div>
Intention is to bind parent form with the array of input control in the child component. Also form will become invalid if one of the input control in child component doesn't have required field.
http://plnkr.co/edit/HznCJfSEiSV28ERqNiWr?p=preview
I love solve old post :)
The key is that your custom Form Component has inside a FormArray, then use "writeValue" to create the formArray, see stackblitz
#Component({
selector: "my-child",
template: `
<h1>Child</h1>
<div *ngFor="let group of formArray.controls" [formGroup]="group">
<input formControlName="firstName" (blur)="_onTouched()" />
<input formControlName="lastName" (blur)="_onTouched()"/>
</div>
`,
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: Child,
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: Child,
multi: true
}
]
})
export class Child implements ControlValueAccessor {
formArray: FormArray;
_onChange;
_onTouched;
writeValue(value: any) {
this.formArray = new FormArray(
value.map(x => {
return new FormGroup({
firstName: new FormControl(x.firstName, Validators.required),
lastName: new FormControl(x.firstName, Validators.required)
});
})
);
this.formArray.valueChanges.subscribe(res => {
this._onChange(res);
});
}
registerOnChange(fn: (value: any) => void) {
this._onChange = fn;
}
registerOnTouched(fn: (value: any) => void) {
this._onTouched = fn;
}
validate({ value }: FormControl) {
return !this.formArray || this.formArray.valid ?
null : { error: "Some fields are not fullfilled" };
}
}
You have to use formArrayName directive and *ngFor like this:
<form [formGroup]="form" (ngSubmit)="sayHello()">
<input formControlName="name"><br>
<input formControlName="email"><br>
<div formArrayName="username">
<div *ngFor="let user of username.controls; let i=index">
<my-child formControlName="i"></my-child>
</div>
</div>
<button type="submit">Register</button>
</form>
And with FormBuilder you have to use FormArray as well.
form = new FormGroup({
name: new FormControl('My Name'),
username: new FormArray([
new FormControl("value"),// ControlValueAccesor is applied only to one control, not two. So you cannot use javascript object like you are using below this line.
{firstName:"Anna", lastName:"Smith"},
{firstName:"Peter", lastName:"Jones"}
])
});
For more details, see this doc.
Case 2: passing FormGroup:
form = new FormGroup({
name: new FormControl('My Name'),
username: new FormArray([
new FormGroup({
firstName: new FormControl('Anna'),
lastName: new FormControl('Smith')
}),
new FormGroup({
firstName: new FormControl('Peper'),
lastName: new FormControl('Jones')
}),
])
})
If you are tring to pass the FormGroup as a ngModel parameters, you can't!

angular 2 on from submit error self.context.onSubmit is not a function

I am using 2.0.0-rc.6 in my angular 2 application.
on form submit I am getting this error - self.context.onSubmit is not a function
also it is appending form values in browser.
http://localhost:3000/register
on submit the page reloading and url become like this.
http://localhost:3000/register?firstName=vcvvc&lastName=vcv&userName=cvv&password=vcv&password=vcv
the codes are
form
<form class="ui form" (ngSubmit)="onSubmit()" #registrationForm="ngForm">
----
----
<button type="submit" class="ui button"> Register</button>
</form>
the service
import { Component } from '#angular/core';
import { User } from '../models/user';
import { RegisterService } from '../services/register.service';
#Component({
selector: 'side-panel',
templateUrl: 'app/components/register.component.html'
})
export class RegisterComponent {
newuser: User = new User();
theText: string;
constructor(private _registerService: RegisterService){
}
onsubmit(){
console.log('form submit clicked..');
this._registerService.sendUser(this.newuser).subscribe(
date =>{
this.newuser = new User();
},
error => console.log(error)
);
}
}
This error occurs when the name of the methods called in an event not matched with the template declaration and inside the class
In your template you have specified onSubmit() as camel case
<form class="ui form" (ngSubmit)="**onSubmit()**" #registrationForm="ngForm">
but inside the class, its not a camelCase "onsubmit()"
onsubmit(){
console.log('form submit clicked..');
this._registerService.sendUser(this.newuser).subscribe(

Angular 2 : How to make POST call using form

I am completely new to Angular 2 and form concept. I am trying to POST form data to a POST API call. like this
POST API : http://localohot:8080/**********
Component :
user: any = {
id: null,
gender: null,
mstatus: null,
birthdate: null,
bloodgroup: null
}
userName: any = {
id: null,
personId: null,
displayName: '',
prefix: null,
givenName: null
}
userAddressJSON: any = {
id: null,
personId: null,
address1: null,
address2: null,
cityVillage: null
}
var form = new FormData();
form.append('userid', new Blob(['' + uid], { type: 'application/json' }));
form.append('user', new Blob([JSON.stringify(this.user)], { type: 'application/json' }));
form.append('userName', new Blob([JSON.stringify(this.userName)], { type: 'application/json' }));
form.append('userAddress', new Blob([JSON.stringify(this.userAddressJSON)], { type: 'application/json' }));
Here, I don't know how to make API call.
In our old application they used form data POST in jQuery. Now I am trying to do the same in Angular 2. When I do the form POST in old application they are sending like this
------WebKitFormBoundarybAWvwmP2VtRxvKA7
Content - Disposition: form - data; name = "userid"; filename = "blob"
Content - Type: application / json
------WebKitFormBoundarybAWvwmP2VtRxvKA7
Content - Disposition: form - data; name = "user"; filename = "blob"
Content - Type: application / json
------WebKitFormBoundarybAWvwmP2VtRxvKA7
Content - Disposition: form - data; name = "userName"; filename = "blob"
Content - Type: application / json
------WebKitFormBoundarybAWvwmP2VtRxvKA7
Content - Disposition: form - data; name = "userAddress"; filename = "blob"
Content - Type: application / json
Can any one help me how to do that form POST in Angular 2.
Here is how I currently make a POST call in my Angular 2 app, because it sounds like you could use a simple example of how to setup a form. Here is the Angular 2 documentation on How to Send Data to the Server.
For even more high level documentation on making AJAX requests in Angular 2 visit this URL.
in my app/app.module.ts
...
import { HttpModule } from '#angular/http';
...
#NgModule({
imports: [
...
HttpModule
...
],
declarations: [
...
],
providers: [ ... ],
bootstrap: [AppComponent],
})
export class AppModule { }
app/system-setup/system-setup.ts
export class SystemSetup {
system_setup_id: number;
name: string;
counter: number;
}
app/form-component/form.component.html (Notice the [(ngModel)], that is what binds the property of the object to the html input element)
<form class="form" (ngSubmit)="saveEdits()" #editSystemSetupForm="ngForm">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="theName" name="name" [(ngModel)]="selectedItem.name" #itemsName="ngModel" required minlength="3"/>
<div [hidden]="itemsName.valid || itemsName.pristine" class="alert alert-danger">Name is required! Min length of 3.</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="">Counter</label>
<input type="number" step=0.01 class="form-control" name="counter" [(ngModel)]="selectedItem.counter" />
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 col-md-offset-8">
<button type="submit" class="btn btn-success" style="float: right; margin-left: 15px;" [disabled]="!editISystemSetupForm.form.valid" >Save</button>
<button type="button" class="btn btn-danger" style="float: right;" (click)="cancelEdits()">Cancel</button>
</div>
</div>
</form>
in my app/form-component/form.component.ts
import { Component, OnInit, Input, Output, EventEmitter } from '#angular/core';
import { Headers, RequestOptions, Http, Response } from '#angular/http';
import { SystemSetup } from '../system-setup/system-setup';
#Component({
selector: 'app-setup-form',
templateUrl: 'setup-form.component.html',
styleUrls: ['setup-form.component.css']
})
export class SetupFormComponent implements OnInit {
#Input() selectedItem: SystemSetup; // The object to be edited
#Output() finishedEditing = new EventEmitter<number>(); // When the POST is done send to the parent component the new id
// Inject the Http service into our component
constructor(private _http: Http) { }
// User is finished editing POST the object to the server to be saved
saveEdits(): void {
let body = JSON.stringify( this.selectedItem );
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this._http.post('http://localhost:8080/**********', body, options)
.map(this.extractData)
.do(
data => {
this.finishedEditing.emit(data.system_setup_id); // Send the parent component the id if the selectedItem
})
.toPromise()
.catch(this.handleError);
}
/**
* Gets the data out of the package from the AJAX call.
* #param {Response} res - AJAX response
* #returns SystemSetup - A json of the returned data
*/
extractData(res: Response): SystemSetup {
let body = res.json();
if (body === 'failed') {
body = {};
}
return body || {};
}
/**
* Handles the AJAX error if the call failed or exited with exception. Print out the error message.
* #param {any} error - An error json object with data about the error on it
* #returns Promise - A promise with the error message in it
*/
private handleError(error: any): Promise<void> {
// 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
return Promise.reject(errMsg);
}
}
This URL is the link to the official Angular 2 documentation site, which is a very good reference for anything an Angular 2 developer could want.