Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 6 pipe does not support constructor

This is my date-formatter-by-timezone.pipe.ts pipe

import { Pipe, PipeTransform } from '@angular/core';
import { CookieService } from 'ngx-cookie-service';

@Pipe({
  name: 'dateFormatterSecByTimezone'
})
export class DateFormatterSecByTimezonePipe implements PipeTransform {

  constructor(private cookieService: CookieService) {}

  timezone:any = parseInt(this.cookieService.get('TM_Z')) * 1000;

  caculateTime(date , timezone){
    //some code here ...
  }

  transform(date: any){
     return this.caculateTime(date , this.timezone)
  }
}

And this is spec file date-formatter-sec.pipe.spec.ts:

import { DateFormatterSecByTimezonePipe } from './date-formatter-sec-by- 
timezone.pipe';

describe('DateFormatterSecByTimezonePipe', () => {
  it('create an instance', () => {
    const pipe = new DateFormatterSecByTimezonePipe();
    expect(pipe).toBeTruthy();
  });
});

In spec file I got this error:

Expected 1 argument, but got 0.
(alias) new DateFormatterSecByTimezonePipe(cookieService: CookieService): 
DateFormatterSecByTimezonePipe
import DateFormatterSecByTimezonePipe

but when I use code above that editor suggested, it still does not work! I imported the constructor in my pipe because I needed to use cookie data in this pipe. How can I fix this error?

like image 287
Abdol Seed Avatar asked Jun 09 '18 05:06

Abdol Seed


People also ask

Can an Angular pipe have a constructor?

Angular 6 pipe does not support constructor.

How do you declare an impure pipe in Angular 6?

If we need some pipe to be called on every change detection, mark the pipe as impure. In the case of impure pipes, Angular will call the transform() method on every change cycle. Multiple instances are created for impure pipes. Impure pipes are not re-used.


2 Answers

The error isn't coming from Angular, it's a simple Typescript problem: you have a constructor with an argument, but in your test you're not passing an argument. This argument is usually served by the DI in Angular. From the testing docs (see link below):

As service consumer, you don't worry about any of this. You don't worry about the order of constructor arguments or how they're created. As a service tester, you must at least think about the first level of service dependencies but you can let Angular DI do the service creation and deal with constructor argument order when you use the TestBed testing utility to provide and create services.

So you could fix this particular test by using

const pipe = new DateFormatterSecByTimezonePipe(null);

But this won't be very useful once you want to write tests that actually assert on the behavior of the pipe. A pipe is essentially like a service here. You can instantiate services yourself in tests if they require no dependencies or you can construct the dependencies in the test as well. If you want Angular to use DI to instantiate services, you need to use its tools:

https://angular.io/guide/testing

This article also explains approaches like using spies.

like image 98
Ingo Bürk Avatar answered Oct 15 '22 08:10

Ingo Bürk


You might want to see this similiar question on SO:

The summary of it is that you should do something like this:

import {SafeHtmlPipe} from './safe-html.pipe';
import {inject} from '@angular/core/testing';
import {DomSanitizer} from '@angular/platform-browser';


describe('SafeHtmlPipe', () => {
  it('create an instance', inject([DomSanitizer], (sanitize: DomSanitizer) => {

    const pipe = new SafeHtmlPipe(sanitize);
    expect(pipe).toBeTruthy();
  }));
});
like image 25
Tomiwa Avatar answered Oct 15 '22 08:10

Tomiwa