Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
122
rated 0 times [  125] [ 3]  / answers: 1 / hits: 18459  / 7 Years ago, fri, march 3, 2017, 12:00:00

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 component 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.component;

@Component({
selector: 'app-new-customer',
templateUrl: './new-customer.component.html',
styleUrls: ['./new-customer.component.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:[''],
company_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 come back and allow them access to view their <b>Invoices</b> &amp; <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=company_name placeholder=Customer Name formControlName=company_name />
<small [hidden]=newCustomerForm.controls.company_name.valid || (newCustomerForm.controls.company_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 component 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.component;

@Component({
selector: 'app-customer-profile',
templateUrl: './customer-profile.component.html',
styleUrls: ['./customer-profile.component.css'],
providers:[NewCustomerComponent]
})
export class CustomerProfileComponent implements OnInit {

@Input() customer: Customer;

constructor() {
console.log(this.customer);
}

ngOnInit() {
}

}

<main>
<header>
<h4>&nbsp;</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);
}


}

More From » angular

 Answers
38

As mentioned a shared service would be a good option. the following example is sharing the Object between the components via service:



Your service:



public sharedCustomer = {};


And the component, 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;
}

[#58689] Wednesday, March 1, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
kelsy

Total Points: 486
Total Questions: 86
Total Answers: 76

Location: El Salvador
Member since Sun, Sep 12, 2021
3 Years ago
;