3

I have a custom pipe for transform temperature value. I want call this pipe on started component (done) and when value of lang change (not working). Can you help me?

My pipe:

@Pipe({
  name: 'temperatureConverter'
})
export class TemperatureConverterPipe implements PipeTransform {
value: number;

constructor(private _translateService: TranslateService, private language: LanguageProvider) {
    this.language.getLanguage().subscribe((value) => {
        this.transform(this.value, value.lang);
    })

}

transform(value: number, unit : string = this.language.selectedLanguage) {
    this.value = value;

    if(value && !isNaN(value)){

        if(unit === 'fr'){
            let tempareature = (value - 32) / 1.8 ;
            return tempareature.toFixed(2) + " °C";
        }
        if(unit === 'en'){
            let tempareature = (value * 32) + 1.8 ;
            return tempareature.toFixed(2) + " F";
        }
    }
    return;
}

}
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Matthis.h
  • 849
  • 3
  • 14
  • 30
  • 1
    Pipes are called from the components, and they return a simple *value* to render. What you're asking doesn't make sense, it can't be dealt with in the pipe alone. – jonrsharpe Jan 08 '19 at 22:11

4 Answers4

2

UPDATE: The solution is to put the the "pure" flag to false. This solves the issue.

@Pipe({
  name: 'TemperatureConverter',
  pure: false
})

--- Previous answer ---

I have the same issue. What I have found out is that having the language as an parameter works. Not what I was hoping for but this could work for someone. This will update the field when the language is changed.

In the constructor of the component using the pipe subscribe as the language changes. The other way (your way) needs you to reload the component:

lang: string;
constructor(private languageService: LanguageService) {
    this.languageService.language$.subscribe(l => this.lang = l);

  }

In the component use the pipe like so:

<span>3 | TemperatureConverter : lang</span
BearZon
  • 291
  • 3
  • 8
  • read more about impure changes within composite objects in custom pipe https://angular.io/guide/pipes#detecting-impure-changes-within-composite-objects – Harsh Patel Mar 30 '23 at 12:01
0

Thanks for your posting blog. I faced same problems related to pipes. I tried to call pipes when the arguments are changed. But it wasn't correct way to synchronize. So instead of that I used function to display when the value changed. Instead of {{ labels | labelFormat }}, I used {{ labelFormat(labels)}}.

And I defined labelFormat function in ts file. Thanks.

  • 1
    Welcome to Stack Overflow? If you want to credit someone you can upvote his post or write a comment, but not an answer – Yannick Funk Mar 18 '21 at 23:52
-1

you first need to register your pipes into your module declarations. After that you can call it inside your html page simply by

{{ myTempDegree | temperatureConverter : 'fr' }}
Derviş Kayımbaşıoğlu
  • 28,492
  • 4
  • 50
  • 72
-1

If you are going to subscribe to an observable inside a pipe, then you must unsubscribe when the pipe is destroyed. You use takeUntil() to automatically unsubscribe using the ngOnDestroy callback.

 export class TemperatureConverterPipe implements PipeTransform, OnDestroy {
     private _destroyed: Subject<void> = new Subject();
     public ngOnDestroy {
        this._destroyed.next();
        this._destroyed.complete();
     }
 }

When you change the internal state of the pipe, then you have to notify Angular that the view has changed. You can do this by using the ChangeDetectorRef.

 private lang: any;

 constructor(private _translateService: TranslateService, 
             private language: LanguageProvider,
             private ref: ChangeDetectorRef) {
     this.language.getLanguage()
          .pipe(takeUntil(this._destroyed))
          .subscribe((value) => {
                 this.lang = value;
                 ref.markForCheck();
           });
}

You can now use the value from the getLanguage() service in the transform function.

transform(value: number, unit?: string) {
   unit = unit || this.lang;
   ....
}

When the service emits a change in the language, then the pipe will trigger change detection on the view and you should see the view updated.

Reactgular
  • 52,335
  • 19
  • 158
  • 208
  • This does not work. You are telling change detection to check, but the underlying primitive or object hasn't changed and therefore the transform function does not get called. – Jeff Howard May 17 '22 at 21:54