pjlamb12
pjlamb12

Reputation: 2422

Angular 2 Custom Pipe not Updating Until Object Saved

I have made a custom Angular 2 pipe to format a phone number from a string of 10 digits to be 'XXX-XXX-XXXX'. The pipe I made works great, but it doesn't update until you edit and then save. It doesn't update on keypress.

I've read a few different places what I could on custom pipes, but I'm not sure which route to go from here. Here's a plunk with the working custom pipe and here's the code as well:

Component:

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      Phone: <input type="text" [ngModel]="obj.phone | phone" />
    </div>
  `,
  directives: [],
  pipes: [PhoneNumber]
})
export class App {
  public obj: any = {
    phone: '8885552233'
  };
  constructor() {
    this.name = 'Angular2'
  }
}

Pipe:

import {PipeTransform, Pipe} from 'angular2/core';

@Pipe({
  name: 'phone'
})
export class PhoneNumber implements PipeTransform{
  transform(value, args) {
    if( value ) {
      var str = "";
        switch( value.length ) {
            case 0:
            case 1:
            case 2:
            case 3:
                str = value;
                break;
            case 4:
            case 5:
            case 6:
                str = value.substring(0, 3) + '-' + value.substring(2, value.length);
                break;
            case 7:
            case 8:
            case 9:
            case 10:
                str = value.substring(0, 3) + '-' + value.substring(3, 6) + '-' + value.substring(6);
                break;
        }
        return str;
    } else {
      return value;
    }
  }
}

If you have any ideas or any advice, I'd really appreciate it!

Thanks!

Upvotes: 3

Views: 2833

Answers (4)

pjlamb12
pjlamb12

Reputation: 2422

Thanks for all of your answers. I ended up using a little bit of @Günter Zöchbauer's answer, with the ngModelChange event, and then had to change the custom pipe to strip out the '-' each time the pipe runs. I updated my plunk to show the changes.

.

Again, thanks for the help and hopefully this helps others in the future.

Upvotes: 0

Angel Angel
Angel Angel

Reputation: 21708

The answer Günter Zöchbauer , solve the problem, but now you say it does not work as expected maybe this helps you, but not if this will be the best approach to what you want

https://plnkr.co/edit/JAxA777p1dX8u2RpmvSA?p=preview

.

I hope it will help

Upvotes: 1

Douglas
Douglas

Reputation: 5087

You have two problems, one a typo-level error, the other more substantial. The typo is that your pipe, on the 4-6 case, should start the second substring at index 3, not 2.

The more substantial error is that your ngModelChange handler needs to perform the reverse of the pipe's transform. Every time ngModelChange fires, it's sending the pipe-modified value back into your model data, which then gets sent back out through the pipe for display so you're getting data filtered through repeated applications of the pipe. But - and this is important - you can't just apply a naive exact reversal of the pipe, removing the fourth and 7th characters; the input your ngModelChange handler receives will be the output of the pipe, modified by one input change, and that will often throw off the position of the inserted dashes, if the dashes are even there - what if the input change is a paste of a whole 10 digit number in a previously empty field? Instead, try searching for and removing dashes, wherever they might be.

Upvotes: 0

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657536

You need to add some action for the ngModelChange event

<input type="text" [ngModel]="obj.phone | phone" (ngModelChange)="obj.phone=$event" />

Upvotes: 2

Related Questions