Issue
By following this tutorial (https://indepth.dev/implementing-multi-language-angular-applications-rendered-on-server/) I've put in place a simple language translation system that works well. But when I launch my tests I have lot of errors I've then upgraded my angular from 8 to 10 that resolve some errors but this one is still remaning and I don't now how to fix it : TypeError: this.missingTranslationHandler.handle is not a function
Sometimes I have also a this.currentLoader.getTranslation is not a function
error don't now why.
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.componenet.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.componenet.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.spec.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/fr.json
{
"default": {
"compA": "Le Composant A fonctionne",
"compB": "Le Composant B fonctionne"
}
}
Solution
If you put TranslationService
in the providers first or if the TranslationModule
in the imports is not well initalized then Karma tell you to add all this providers that you don't need.
What I've done is importing directly the I18nModule
instead of the TranslationModule
and kept only the TranslationService
in the providers.
home/home.component.spec.ts
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [HomeComponent],
imports: [
I18nModule
],
providers: [
TranslateService
]
})
.compileComponents();
}));
Answered By - TheSmartMonkey
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.