I'm submitting a ... (check one with "x")
[x] bug report => check the FAQ and search github for a similar issue or PR before submitting
[ ] support request => check the FAQ and search github for a similar issue before submitting
[ ] feature request
Current behavior
Translations are not applied on pipes on the last version (8.0.0).
Expected/desired behavior
Show translated texts on view.
Reproduction of the problem
I've changed my project to support Angular 5.0.2 and ngx-translate 8.0.0 versions, so my loader now injects HttpClient instead of Http and my NgModule imports my HttpClientModule.
export function HttpLoaderFactory (http: HttpClient) {
return new TranslateHttpLoader(http, baseUrl + 'assets/i18n/', '.json');
}
@NgModule({
declarations: [
...
],
imports: [
BrowserModule,
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
}),
...
],
providers: [
{provide: HTTP_INTERCEPTORS, useClass: HttpApiInterceptor, multi: true},
...
],
bootstrap: [ AppComponent ]
})
export class AppModule {
}
The problem is that project builds correctly but now translations are not applied on pipes (view is showing nothing, even the text without translation). The "en.json" file is being loaded successfully.
I've debugged the Pipe's code and it's getting inside it with the correct text but translation value is not changed.
You can see this plunker http://plnkr.co/edit/nFlPoqh9X2yPGMIbxqDH?p=info which is a copy of the official demo of ngx-translate including an interceptor.
What is the expected behavior?
Ngx-translate should translate correctly all the piped texts, as in previous versions.
What is the motivation / use case for changing the behavior?
To detect some future problems with the library.
Please tell us about your environment:
Sorry I removed my question, I was just investigating the issue. The problem is when you import the library directly into an interceptor (from constructor). In order to use the library in the interceptor, you must inject it and remove it from the constructor.
Was my fault, i wasn't returning the results on the "map" inside intercept method. So jsons was passing over my interceptor without being exposed.
@Injectable()
export class HttpApiInterceptor implements HttpInterceptor {
constructor () {
}
intercept (req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req)
.map(res => {
if (res instanceof HttpResponse) {
// If response is "204 Not Content" then returns an empty array list
if (res.status === 204) {
return [];
}
}
return res; <--- I wasn't returning nothing here
});
}
}
Closed!
@ivandatio
I have same problem. But your solution doesn't helped me.
import {Observable} from 'rxjs/Observable';
import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse, HttpParams, HttpResponse} from '@angular/common/http';
import 'rxjs/add/operator/first';
import {SessionStorageService} from 'ng2-webstorage';
import { ToasterService } from 'angular2-toaster';
import {Router} from '@angular/router';
@Injectable()
export class HttpInterceptorService implements HttpInterceptor {
private toasterService: ToasterService;
constructor(
public router: Router,
private sessionStorage: SessionStorageService,
toasterService: ToasterService
) {
this.toasterService = toasterService;
}
intercept(req: HttpRequest<any>, next: HttpHandler): any {
const url = '';
req = req.clone({
url: url + req.url,
// responseType: 'text',//needed to avoid problem witch shows 201 status as error. don't forget to JSON.parse data
headers: req.headers.set('Authorization', this.sessionStorage.retrieve('access_token'))
});
return next.handle(req)
.map(res => {
console.log('result', res);
if (res instanceof HttpResponse) {
// If response is "204 Not Content" then returns an empty array list
if (res.status === 204) {
return [];
}
}
return res;
});
}
}
app.module
...
export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
...
@NgModule({
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
appRouter,
ToasterModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: createTranslateLoader,
deps: [Http]
}
}),
AuthorizationModule,
Ng2Webstorage,
BsDropdownModule.forRoot(),
TooltipModule.forRoot(),
ModalModule.forRoot(),
SidebarModule.forRoot(),
BrowserAnimationsModule
],
declarations: [
AppComponent,
...APP_CONTAINERS,
...APP_COMPONENTS,
...APP_DIRECTIVES
],
providers: [
{provide: HTTP_INTERCEPTORS, useClass: HttpInterceptorService, multi: true},
CardService,
TokenService,
MainRequestService
],
bootstrap: [AppComponent]
})
export class AppModule {
}
@aitboudad If I'm trying to use your variant. I get
ERROR in http-interceptor.service.ts (16,9): Type 'Observable
| H...' is not assignable to type 'Observable >'.
Type 'any[] | HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse| HttpUserEven...' is not assignable to type 'HttpEvent '.
Type 'any[]' is not assignable to type 'HttpEvent'.
Type 'any[]' is not assignable to type 'HttpUserEvent'.
Property 'type' is missing in type 'any[]'.
This is my final intercept method:
intercept (req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req)
.map(res => {
if (res instanceof HttpResponse) {
// If response is "204 Not Content" then returns an empty array list
if (res.status === 204) {
const result: any = res;
result.body = { data: [] };
return result;
}
}
return res;
})
}
And I'm seeing that on imports:
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: createTranslateLoader,
deps: [Http] <---- It should be HttpClient
}
}),
oh. my mistake. i was trying to load translation with old http. and forgot to revert changes,
thx for fast reply.
Hello,
I have a related problem with this topic. HttpLoader has been working well until I add HttpInterceptor service to add header authentication token to my http request. It takes all "translations request" but it is not necessary.
I try to filter http request but it is impossible and it overloads the app.
Any suggestions, please?
```import { Injectable } from '@angular/core';
import {
HttpHandler,
HttpInterceptor,
HttpRequest,
HttpEvent
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
import { mergeMap } from 'rxjs/operators';
@Injectable()
export class HeaderInterceptor implements HttpInterceptor {
constructor(private auth: AuthService) {}
intercept(
request: HttpRequest
next: HttpHandler
): Observable
return this.auth.getToken().pipe(
mergeMap((token: string) => {
if (token) {
// clone and modify the request
request = request.clone({
setHeaders: {
FIREBASE_AUTH_TOKEN: token
}
});
}
console.log(request);
return next.handle(request);
})
);
}
`}
### app.module.ts
@NgModule({
declarations: [AppComponent],
imports: [
AppRoutingModule,
HttpClientModule,
ReactiveFormsModule,
MaterialModule,
SharedModule.forRoot(),
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: createTranslateLoader,
deps: [HttpClient]
}
})
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: HeaderInterceptor,
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule {}
export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
Finally got a solution to make Translation work with HttpInterceptors ..
1-) First change the createTranslateLoader wich depends on HttpClient methods in app.modules.ts to use custom translateHttpLoaderFactory wich depends on HttpBackend .
=>> relace
export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
==> By
export function translateHttpLoaderFactory(httpBackend: HttpBackend): TranslateHttpLoader {
return new TranslateHttpLoader(new HttpClient(httpBackend));
}
2-) in your app.modules inports array use the new TranslateLoder Factory
=>> replace
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: createTranslateLoader,
deps: [HttpClient]
}
})
==> With
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: translateHttpLoaderFactory,
deps: [HttpBackend]
}
})
and you are ready to go. 馃憤
@PavelFoujeu You just saved my life. Thank you, you truly are a wonderful human being.
translateHttpLoaderFactory
Finally got a solution to make Translation work with HttpInterceptors ..
1-) First change the createTranslateLoader wich depends on HttpClient methods in app.modules.ts to use custom translateHttpLoaderFactory wich depends on HttpBackend .=>> relace
export function createTranslateLoader(http: HttpClient) { return new TranslateHttpLoader(http, './assets/i18n/', '.json'); }==> By
export function translateHttpLoaderFactory(httpBackend: HttpBackend): TranslateHttpLoader { return new TranslateHttpLoader(new HttpClient(httpBackend)); }2-) in your app.modules inports array use the new TranslateLoder Factory
=>> replace
TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: createTranslateLoader, deps: [HttpClient] } })==> With
TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: translateHttpLoaderFactory, deps: [HttpBackend] } })and you are ready to go.
Not working,getting the below error:
core.js:1673 ERROR TypeError: _this.handler.handle is not a function
at MergeMapSubscriber.project (http.js:974)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext (mergeMap.js:61)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._next (mergeMap.js:51)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:55)
at Observable._subscribe (scalar.js:5)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (Observable.js:42)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:28)
at MergeMapOperator.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapOperator.call (mergeMap.js:29)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:23)
at FilterOperator.push../node_modules/rxjs/_esm5/internal/operators/filter.js.FilterOperator.call (filter.js:15)
Most helpful comment
Finally got a solution to make Translation work with HttpInterceptors ..
1-) First change the createTranslateLoader wich depends on HttpClient methods in app.modules.ts to use custom translateHttpLoaderFactory wich depends on HttpBackend .
=>> relace
export function createTranslateLoader(http: HttpClient) { return new TranslateHttpLoader(http, './assets/i18n/', '.json'); }==> By
export function translateHttpLoaderFactory(httpBackend: HttpBackend): TranslateHttpLoader { return new TranslateHttpLoader(new HttpClient(httpBackend)); }2-) in your app.modules inports array use the new TranslateLoder Factory
=>> replace
TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: createTranslateLoader, deps: [HttpClient] } })==> With
TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: translateHttpLoaderFactory, deps: [HttpBackend] } })and you are ready to go. 馃憤