1

I am a newbie at Angular, and junior in general, and got a question for you.

If I have an input which user sets, but I need to use the input in different view (different template), how can I manage to do so?

I've read a lot of articles, but none was really helpful with my situation.

One idea I read about and thought of using was creating a service, which I inject in the templates where user needs to set values, or I need to display them. In such case I can write to variable, and read from it, right?

Here is a sample code of input form from template:

    <form>
      <mat-form-field class="size">
        <mat-label>Provide the customer name</mat-label>
        <input matInput #customerName>
      </mat-form-field>
    </form>

User would enter customer name, and it would save it as a variable in typescript file, from where I can re-use it elsewhere.

The main idea is: How to add input field as typescript variable and re-use the entered variable in different templates? By making the variable global? And how to do such a thing?

I hope I made it clear. If anything, just say and I will re-make it so it's easiet to understand.

--- EDIT ---

In this posts answer they get to my problem, the person who gave the answer to this link with stackblitz code, which I suppose is exactly what I wanted, but I can not manage to get it to work with HTML code I provided in my post previously

Here is my updated code: Component 1 TS file

    import { Component, OnInit } from '@angular/core';
import { VariablesService } from '../../variables.service';
import { Subject } from 'rxjs';

@Component({
  selector: 'app-Step2',
  templateUrl: './Step2.component.html',
  styleUrls: ['./Step2.component.css']
})
export class Step2Component implements OnInit {

  constructor(public variablesService: VariablesService) {
    this.customerNameSource = this.variablesService.customerName;
   }

  ngOnInit() {
  }

  customerNameSource: Subject<string>;
  customerName: string = "";

  saveActions() {
    this.variablesService.changeCustomerName(this.customerName);
  }
}

Component 1 HTML file

<div>
  <form>
    <mat-form-field class="size">
      <mat-label>Provide the customer name</mat-label>
      <input matInput [(ngModel)]="customerName">
    </mat-form-field>
  </form>
</div>

<div class="next">
  <button mat-button (click)="saveActions()" routerLink="/step1">Previous</button>
  <button mat-button (click)="saveActions()" routerLink="/step3">Next</button>
</div>

Component 2 TS file

import { Component, OnInit } from '@angular/core';
import { VariablesService } from '../../variables.service';
import { Subject } from 'rxjs';

@Component({
  selector: 'app-Step3',
  templateUrl: './Step3.component.html',
  styleUrls: ['./Step3.component.css']
})
export class Step3Component implements OnInit {

  constructor(public variablesService: VariablesService) {
    this.customerNameSource = this.variablesService.customerName;

    this.customerNameSource.subscribe(value => {
      this.customerName = value;
    })
   }

  ngOnInit() {
  }

  customerNameSource: Subject<string>;
  public customerName: string = "";
}

Component 2 HTML file

<div>
  <h6>{{ customerName }}</h6>
</div>

<div class="next">
  <button mat-button routerLink="/step2">Previous(test)</button>
  <button mat-button routerLink="/step4">NEXT(test)</button>
</div>

Service TS file

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class VariablesService {

constructor() { }

_customerName: Subject<string> = new Subject();
get customerName() : Subject<string> {
  return this._customerName;
}
set customerName(cstName: Subject<string>) {
  this._customerName = cstName;
}


changeCustomerName(n: string) {
  this.customerName.next(n);
}    
}

But it still doesn't work as expected - By entering something in component 1 input, there is nothing showing up in component 2.

Yes, I have added service as provider in app.module.ts

2 Answers2

0

I am not sure about the requirement.

If by different template, you mean another component, you can either use a service shared by the two components or you can "bubble" the event depending on the relationships (siblings, parent and children components) by the use of EventEmitter and @Output (https://angular.io/start#output)

If your problem is about getting the value of the input, please read through this and focus on the ngModel binding for the value. https://angular.io/guide/forms.

Or you might lso be interested by reactiveForm and the usage of formControl https://angular.io/guide/reactive-forms

Tino
  • 21
  • 7
  • I added some more info to my question, please check it out. Other than that I will check out the info you provided a bit later. – CreativeOne Oct 24 '19 at 11:56
  • Thanks for the help, it kinda helped, but wasn't enough. would give you +1, but my reputation is too low. – CreativeOne Oct 28 '19 at 14:21
0

So the answer to my question can be found on this site.

I used service as previously mentioned, just the way it is implemented is different, and for me - easier. HTML stays as it is besides adding name="custmerName" next to ngModel.

For typescript files I removed old code, and added this code:

Component 1 TS code

import { Component, OnInit, Input } from '@angular/core';
import { VariablesService } from '../../variables.service';

@Component({
  selector: 'app-Step2',
  templateUrl: './Step2.component.html',
  styleUrls: ['./Step2.component.css']
})
export class Step2Component implements OnInit {

  customerName: string;

  constructor(public variablesService: VariablesService) {

   }

  ngOnInit() {
    this.variablesService.currentCustomerName.subscribe(customerName => this.customerName = customerName)
  }


  saveActions() {
    this.variablesService.changeCustomerData(this.customerName)
  }
}

Component 2 TS code

import { Component, OnInit, Input } from '@angular/core';
import { VariablesService } from '../../variables.service';

@Component({
  selector: 'app-Step3',
  templateUrl: './Step3.component.html',
  styleUrls: ['./Step3.component.css']
})
export class Step3Component implements OnInit {

customerName: string;

  constructor(public variablesService: VariablesService) {

   }

  ngOnInit() {
    this.variablesService.currentCustomerName.subscribe(customerName => this.customerName = customerName)
  }
}

Service TS code

import { Injectable } from '@angular/core';
import { Subject, BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class VariablesService {

  constructor() { }

  private customerNameSource = new BehaviorSubject('');
  currentCustomerName = this.customerNameSource.asObservable();


  changeCustomerData(customerName: string) {
    this.customerNameSource.next(customerName);
  }
}