Angular Проверка кармы ngx-translate завершается ошибкой TypeError: this.missingTranslationHandler.handle не является функцией - PullRequest
0 голосов
/ 04 августа 2020

Следуя этому руководству (https://indepth.dev/implementing-multi-language-angular-applications-rendered-on-server/), я создал простую систему языкового перевода, которая хорошо работает. Но когда я запускаю свои тесты, у меня много ошибок. Затем я обновил свой angular с 8 до 10, которые устраняют некоторые ошибки, но этот все еще восстанавливается, и я не знаю, как его исправить: TypeError: this.missingTranslationHandler.handle is not a function

Иногда у меня также возникает ошибка this.currentLoader.getTranslation is not a function, теперь не знаю почему.

package. json

"dependencies": {
    "@angular/animations": "~10.0.7",
    "@angular/common": "~10.0.7",
    "@angular/compiler": "~10.0.7",
    "@angular/core": "~10.0.7",
    "@angular/forms": "~10.0.7",
    "@angular/platform-browser": "~10.0.7",
    "@angular/platform-browser-dynamic": "~10.0.7",
    "@angular/router": "~10.0.7",
    "@ngx-translate/core": "^13.0.0",
    "@ngx-translate/http-loader": "^6.0.0",
    "rxjs": "~6.6.2",
    "tslib": "^2.0.0",
    "zone.js": "~0.10.3"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.1000.5",
    "@angular/cli": "~10.0.5",
    "@angular/compiler-cli": "~10.0.7",
    "@angular/language-service": "~10.0.7",
    "@types/node": "^12.11.1",
    "@types/jasmine": "~3.3.8",
    "@types/jasminewd2": "~2.0.3",
    "codelyzer": "^6.0.0",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~5.0.0",
    "karma": "~5.0.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~3.0.2",
    "karma-jasmine": "~3.3.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "protractor": "~7.0.0",
    "ts-node": "~7.0.0",
    "tslint": "~6.1.0",
    "typescript": "~3.9.7"
  }

i18n / i18n.module.ts

@NgModule({
  imports: [
    HttpClientModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: translateLoaderFactory,
        deps: [HttpClient]
      }
    }),
  ],
  exports: [TranslateModule]
})
export class I18nModule {
  constructor(translate: TranslateService) {
    translate.addLangs(['en', 'fr']);
    const browserLang = translate.getBrowserLang();
    translate.use(browserLang.match(/en|fr/) ? browserLang : 'en');
  }
}

export function translateLoaderFactory(httpClient: HttpClient) {
  return new TranslateHttpLoader(httpClient);
}

app.module.ts

@NgModule({
  declarations: [
    AppComponent,
    NavigationComponent,
    HomeComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    I18nModule,
    TranslateModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

home / home.compon enet .ts

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

  public currentLang: string;
  text = '';

  constructor(private changeDetectorRef: ChangeDetectorRef, public translate: TranslateService) { }

  ngOnInit() {
    this.currentLang = this.translate.currentLang;
    this.translate.onLangChange.subscribe((event: LangChangeEvent) => {
      this.currentLang = event.lang;
      this.changeDetectorRef.detectChanges();
      this.translateText();
    });
    console.log('text: ', this.text);
  }

  translateText() {
    this.translate.get('default').subscribe((data: any) => {
      this.text = data.compA;
      console.log('text: ', this.text);
    });
  }

}

home / home.compon enet. html

<select #langSelect (change)="translate.use(langSelect.value)">
    <option *ngFor="let lang of translate.getLangs()" [value]="lang"
        [attr.selected]="lang === translate.currentLang ? '' : null">{{lang}}</option>
</select>

<p>{{'default.compA' | translate}}</p>

<p translate>default.compB</p>

<p>{{text}}</p>

home / home.component.spe c .ts

describe('HomeComponent', () => {
  let component: HomeComponent;
  let fixture: ComponentFixture<HomeComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [HomeComponent],
      imports: [
        TranslateModule
      ],
      providers: [
        TranslateService,
        TranslateStore,
        TranslateLoader,
        TranslateCompiler,
        TranslateParser,
        MissingTranslationHandler,
        { provide: USE_DEFAULT_LANG, useValue: undefined },
        { provide: USE_STORE, useValue: undefined },
        { provide: USE_EXTEND, useValue: undefined },
        { provide: DEFAULT_LANGUAGE, useValue: undefined }
      ]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(HomeComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

assets / i18n / en. json

{
    "default": {
        "compA": "Component A works",
        "compB": "Component B works"
    }
}

assets / i18n / фр. json

{
    "default": {
        "compA": "Le Composant A fonctionne",
        "compB": "Le Composant B fonctionne"
    }
}

1 Ответ

0 голосов
/ 11 августа 2020

Если вы сначала укажете TranslationService в поставщиках или если TranslationModule в импорте недостаточно инициализирован, то Карма скажет вам добавить всех этих поставщиков, которые вам не нужны.

What I 've done' импортирует напрямую I18nModule вместо TranslationModule и сохраняет только TranslationService в провайдерах.

home / home.component.spe c .ts

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [HomeComponent],
      imports: [
        I18nModule
      ],
      providers: [
        TranslateService
      ]
    })
      .compileComponents();
  }));
...