I have a form which allows user to create an account, once the user clicks on submit button the user is navigated to another page with the details of that account they have create. The issue I am having is passing that object to the details view.
For example here is my ponent for the form,
import {Component, OnInit, OnDestroy, Input} from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import {Customer} from "../model/customer";
import {Router } from '@angular/router';
import {CustomerService} from "../service/customer.service";
import {CustomerProfileComponent} from "../customer-profile/customer-profileponent";
@Component({
selector: 'app-new-customer',
templateUrl: './new-customerponent.html',
styleUrls: ['./new-customerponent.css']
})
export class NewCustomerComponent implements OnInit {
@Input() customer: Customer;
//this is only dev data do not use this in prod
private countries = [];
private customerSources = [];
private secondarySources =[];
//Create the forum group
public newCustomerForm: FormGroup;
public submitted: boolean; // keep track on whether form is submitted
constructor(private fb: FormBuilder, public customerService: CustomerService,private router: Router) {
this.countries = [
{value:'UK'},
{value:'Germany'},
{value:'Turkey'},
{value:'Italy'}
];
this.customerSources = [
{value: 'Through a friend or colleague (not a Client)'},
{value: 'Through an existing Client'},
{value: 'Direct Sales (e.g. cold call, direct mail, email)'},
{value: 'Web Search e.g. Google'}
];
this.secondarySources = [
{value: '1st Hire'},
{value: 'A Test Client With A Long Business Name'},
{value: 'Abbigail West'}
];
}
ngOnInit() {
this.newCustomerForm = this.fb.group({
id:[''],
pany_name: ['', [<any>Validators.required, <any>Validators.minLength(5)]],
vat:[''],
address:[''],
country:[''],
first_name:[''],
surname:[''],
phone:[''],
email:['',[<any>Validators.required, <any>Validators.minLength(5)]],
customer_sources:[''],
secondary_sources:['']
});
}
here is my form html,
<form [formGroup]="newCustomerForm" novalidate (ngSubmit)="saveNewCustomer(newCustomerForm.value, newCustomerForm.valid)">
<section>
<aside>
<p>Once you've added your new <b>Client</b>, you can e back and allow them access to view their <b>Invoices</b> & <b>Payments</b> - they can also make <b>Payments</b> via Paypal if you have it enabled.</p>
</aside>
<input type="hidden" name="id" formControlName="id"/>
<h4>New Client Details</h4>
<md-input-container>
<input mdInput type="text" name="pany_name" placeholder="Customer Name" formControlName="pany_name" />
<small [hidden]="newCustomerForm.controlspany_name.valid || (newCustomerForm.controlspany_name.pristine && !submitted)">
Customer Name is required (minimum 5 characters).
</small>
</md-input-container>
<md-input-container>
<input mdInput type="text" name="vat" placeholder="VAT Number" formControlName="vat"/>
</md-input-container>
<md-input-container>
<input mdInput type="text" name="address" placeholder="Address" formControlName="address" />
</md-input-container>
<md-select placeholder="Country" name="country" formControlName="country" >
<md-option *ngFor="let country of countries" [value]="country.value" >
{{country.value}}
</md-option>
</md-select>
<h4>Your Primary Contact</h4>
<div class="left-column">
<md-input-container>
<input mdInput type="text" name="first_name" placeholder="First Name" formControlName="first_name" />
</md-input-container>
</div>
<div class="left-column">
<md-input-container>
<input mdInput type="text" name="surname" placeholder="surname" formControlName="surname" />
</md-input-container>
</div>
<div class="clearfix"></div>
<div class="left-column">
<div class="left-column">
<md-input-container>
<input mdInput type="text" name="phone" placeholder="Phone" formControlName="phone"/>
</md-input-container>
</div>
</div>
<div class="right-column">
<div class="left-column">
<md-input-container>
<input mdInput type="text" name="email" placeholder="Email" formControlName="email"/>
<small [hidden]="newCustomerForm.controls.email.valid || (newCustomerForm.controls.email.pristine && !submitted)">
Email is required (minimum 5 characters).
</small>
</md-input-container>
</div>
</div>
<div class="clearfix"></div>
<h4>Customer Source</h4>
<div class="left-column">
<md-select placeholder="How were you introduced to this Client?" formControlName="customer_sources">
<md-option *ngFor="let cs of customerSources" [value]="cs.value" >
{{cs.value}}
</md-option>
</md-select>
</div>
<div class="right-column">
<md-select placeholder="Which Client introduced you?" formControlName="secondary_sources">
<md-option *ngFor="let ss of secondarySources" [value]="ss.value" >
{{ss.value}}
</md-option>
</md-select>
</div>
<div class="clearfix"></div>
</section>
<aside>
<div class="right-aside">
<button type="submit" class="cancel">Cancel</button>
<button type="submit" class="save">Save</button>
</div>
<div class="clearfix"></div>
</aside>
</form>
Customer service is in my app.module. Here I am saving the data and moving the user on to the new page.
saveNewCustomer(customer: Customer, isValid: boolean){
if(isValid){
this.submitted = true; // set form submit to true
this.customerService.saveNewCustomer(customer)
.subscribe(
res => this.customer,
error => console.log(<any>error)
);
this.router.navigateByUrl('/earning/customers/profile');
}
}
}
And this is the ponent I would like the customer object to use so it be present in the view.
import {Component, OnInit, Input} from '@angular/core';
import {Customer} from "../model/customer";
import {NewCustomerComponent} from "../new-customer/new-customerponent";
@Component({
selector: 'app-customer-profile',
templateUrl: './customer-profileponent.html',
styleUrls: ['./customer-profileponent.css'],
providers:[NewCustomerComponent]
})
export class CustomerProfileComponent implements OnInit {
@Input() customer: Customer;
constructor() {
console.log(this.customer);
}
ngOnInit() {
}
}
<main>
<header>
<h4> </h4>
<h1><strong><i></i>Customer profile</strong></h1>
</header>
<article>
<section>
<p></p>
<p>
{{customer}}
</p>
</section>
</article>
</main>
But customer is undefined in the CustomerProfileComponent. I am not sure what I am doing wrong. if anyone can point me in the right direction would be much appreciated.
Update to include service class based on suggestion
import { Injectable } from '@angular/core';
import {Http, Response, Headers, RequestOptions} from '@angular/http';
import {CookieService} from "angular2-cookie/services/cookies.service";
import {Observable, Subject} from "rxjs";
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import {Customer} from "../model/customer";
@Injectable()
export class CustomerService {
private csrfToken;
private newCustomerUrl = "/earning/customers/new";
private customer = new Subject<Object>();
customer$ = this.customer.asObservable();
constructor(public http: Http, private cookieService: CookieService) {
this.getCsrfToken();
}
getCsrfToken(){
this.csrfToken = this.cookieService.get("PLAY_SESSION").substring(this.cookieService.get("PLAY_SESSION").indexOf("csrfToken"));
}
saveNewCustomer(customer:Customer): Observable<Customer>{
let headers = new Headers({
'Content-Type':'application/json'
});
let options = new RequestOptions({ headers: headers });
return this.http.post(this.newCustomerUrl+"?"+this.csrfToken, customer, options) // ...using post request
.map((res:Response) => res.json()) // ...and calling .json() on the response to return data
.catch(this.handleError); //...errors if any
}
private handleError (error: Response) {
return Observable.throw('Internal server error: ' + error);
}
emitCustomer(customer) {
this.customer.next(customer);
}
}
I have a form which allows user to create an account, once the user clicks on submit button the user is navigated to another page with the details of that account they have create. The issue I am having is passing that object to the details view.
For example here is my ponent for the form,
import {Component, OnInit, OnDestroy, Input} from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import {Customer} from "../model/customer";
import {Router } from '@angular/router';
import {CustomerService} from "../service/customer.service";
import {CustomerProfileComponent} from "../customer-profile/customer-profile.ponent";
@Component({
selector: 'app-new-customer',
templateUrl: './new-customer.ponent.html',
styleUrls: ['./new-customer.ponent.css']
})
export class NewCustomerComponent implements OnInit {
@Input() customer: Customer;
//this is only dev data do not use this in prod
private countries = [];
private customerSources = [];
private secondarySources =[];
//Create the forum group
public newCustomerForm: FormGroup;
public submitted: boolean; // keep track on whether form is submitted
constructor(private fb: FormBuilder, public customerService: CustomerService,private router: Router) {
this.countries = [
{value:'UK'},
{value:'Germany'},
{value:'Turkey'},
{value:'Italy'}
];
this.customerSources = [
{value: 'Through a friend or colleague (not a Client)'},
{value: 'Through an existing Client'},
{value: 'Direct Sales (e.g. cold call, direct mail, email)'},
{value: 'Web Search e.g. Google'}
];
this.secondarySources = [
{value: '1st Hire'},
{value: 'A Test Client With A Long Business Name'},
{value: 'Abbigail West'}
];
}
ngOnInit() {
this.newCustomerForm = this.fb.group({
id:[''],
pany_name: ['', [<any>Validators.required, <any>Validators.minLength(5)]],
vat:[''],
address:[''],
country:[''],
first_name:[''],
surname:[''],
phone:[''],
email:['',[<any>Validators.required, <any>Validators.minLength(5)]],
customer_sources:[''],
secondary_sources:['']
});
}
here is my form html,
<form [formGroup]="newCustomerForm" novalidate (ngSubmit)="saveNewCustomer(newCustomerForm.value, newCustomerForm.valid)">
<section>
<aside>
<p>Once you've added your new <b>Client</b>, you can e back and allow them access to view their <b>Invoices</b> & <b>Payments</b> - they can also make <b>Payments</b> via Paypal if you have it enabled.</p>
</aside>
<input type="hidden" name="id" formControlName="id"/>
<h4>New Client Details</h4>
<md-input-container>
<input mdInput type="text" name="pany_name" placeholder="Customer Name" formControlName="pany_name" />
<small [hidden]="newCustomerForm.controls.pany_name.valid || (newCustomerForm.controls.pany_name.pristine && !submitted)">
Customer Name is required (minimum 5 characters).
</small>
</md-input-container>
<md-input-container>
<input mdInput type="text" name="vat" placeholder="VAT Number" formControlName="vat"/>
</md-input-container>
<md-input-container>
<input mdInput type="text" name="address" placeholder="Address" formControlName="address" />
</md-input-container>
<md-select placeholder="Country" name="country" formControlName="country" >
<md-option *ngFor="let country of countries" [value]="country.value" >
{{country.value}}
</md-option>
</md-select>
<h4>Your Primary Contact</h4>
<div class="left-column">
<md-input-container>
<input mdInput type="text" name="first_name" placeholder="First Name" formControlName="first_name" />
</md-input-container>
</div>
<div class="left-column">
<md-input-container>
<input mdInput type="text" name="surname" placeholder="surname" formControlName="surname" />
</md-input-container>
</div>
<div class="clearfix"></div>
<div class="left-column">
<div class="left-column">
<md-input-container>
<input mdInput type="text" name="phone" placeholder="Phone" formControlName="phone"/>
</md-input-container>
</div>
</div>
<div class="right-column">
<div class="left-column">
<md-input-container>
<input mdInput type="text" name="email" placeholder="Email" formControlName="email"/>
<small [hidden]="newCustomerForm.controls.email.valid || (newCustomerForm.controls.email.pristine && !submitted)">
Email is required (minimum 5 characters).
</small>
</md-input-container>
</div>
</div>
<div class="clearfix"></div>
<h4>Customer Source</h4>
<div class="left-column">
<md-select placeholder="How were you introduced to this Client?" formControlName="customer_sources">
<md-option *ngFor="let cs of customerSources" [value]="cs.value" >
{{cs.value}}
</md-option>
</md-select>
</div>
<div class="right-column">
<md-select placeholder="Which Client introduced you?" formControlName="secondary_sources">
<md-option *ngFor="let ss of secondarySources" [value]="ss.value" >
{{ss.value}}
</md-option>
</md-select>
</div>
<div class="clearfix"></div>
</section>
<aside>
<div class="right-aside">
<button type="submit" class="cancel">Cancel</button>
<button type="submit" class="save">Save</button>
</div>
<div class="clearfix"></div>
</aside>
</form>
Customer service is in my app.module. Here I am saving the data and moving the user on to the new page.
saveNewCustomer(customer: Customer, isValid: boolean){
if(isValid){
this.submitted = true; // set form submit to true
this.customerService.saveNewCustomer(customer)
.subscribe(
res => this.customer,
error => console.log(<any>error)
);
this.router.navigateByUrl('/earning/customers/profile');
}
}
}
And this is the ponent I would like the customer object to use so it be present in the view.
import {Component, OnInit, Input} from '@angular/core';
import {Customer} from "../model/customer";
import {NewCustomerComponent} from "../new-customer/new-customer.ponent";
@Component({
selector: 'app-customer-profile',
templateUrl: './customer-profile.ponent.html',
styleUrls: ['./customer-profile.ponent.css'],
providers:[NewCustomerComponent]
})
export class CustomerProfileComponent implements OnInit {
@Input() customer: Customer;
constructor() {
console.log(this.customer);
}
ngOnInit() {
}
}
<main>
<header>
<h4> </h4>
<h1><strong><i></i>Customer profile</strong></h1>
</header>
<article>
<section>
<p></p>
<p>
{{customer}}
</p>
</section>
</article>
</main>
But customer is undefined in the CustomerProfileComponent. I am not sure what I am doing wrong. if anyone can point me in the right direction would be much appreciated.
Update to include service class based on suggestion
import { Injectable } from '@angular/core';
import {Http, Response, Headers, RequestOptions} from '@angular/http';
import {CookieService} from "angular2-cookie/services/cookies.service";
import {Observable, Subject} from "rxjs";
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import {Customer} from "../model/customer";
@Injectable()
export class CustomerService {
private csrfToken;
private newCustomerUrl = "/earning/customers/new";
private customer = new Subject<Object>();
customer$ = this.customer.asObservable();
constructor(public http: Http, private cookieService: CookieService) {
this.getCsrfToken();
}
getCsrfToken(){
this.csrfToken = this.cookieService.get("PLAY_SESSION").substring(this.cookieService.get("PLAY_SESSION").indexOf("csrfToken"));
}
saveNewCustomer(customer:Customer): Observable<Customer>{
let headers = new Headers({
'Content-Type':'application/json'
});
let options = new RequestOptions({ headers: headers });
return this.http.post(this.newCustomerUrl+"?"+this.csrfToken, customer, options) // ...using post request
.map((res:Response) => res.json()) // ...and calling .json() on the response to return data
.catch(this.handleError); //...errors if any
}
private handleError (error: Response) {
return Observable.throw('Internal server error: ' + error);
}
emitCustomer(customer) {
this.customer.next(customer);
}
}
Share
Improve this question
edited Mar 3, 2017 at 14:54
Limpep
asked Mar 3, 2017 at 11:37
LimpepLimpep
4993 gold badges11 silver badges22 bronze badges
4
- post the related template code – Avinash Raj Commented Mar 3, 2017 at 11:39
-
Either paste your
html
code, or set up a service which municates between ponents a shown here: angular.io/docs/ts/latest/cookbook/… – Code Ratchet Commented Mar 3, 2017 at 11:50 - @AvinashRaj I have pasted in my html code. Thanks – Limpep Commented Mar 3, 2017 at 13:28
- @CodeRatchetI have pasted in my html code. Thanks – Limpep Commented Mar 3, 2017 at 13:29
1 Answer
Reset to default 3As mentioned a shared service would be a good option. the following example is sharing the Object between the ponents via service:
Your service:
public sharedCustomer = {};
And the ponent, after that you have received your customer from the api, push the customer to the service:
this.customerService.saveNewCustomer(customer)
.subscribe(res => {
this.customer = res;
this.customerService.sharedCustomer = this.customer;
this.router.navigateByUrl('/earning/customers/profile');
});
}
Notice that I'm emitting the customer inside the subscription, as well as the navigation, to ensure that the customer gets stored in the service properly, as well as not navigating away from page before that.
Then in your detail page:
ngOnInit() {
this.customer = this.customerService.sharedCustomer;
}