Navigating & Passing Data Between Pages Ionic 2 - json

I'm having some issues while navigating between pages with Ionic2.
I have a List of Data, that I got from a data.json
Here is the list
I want to get details:
Example - From "A"
The data that I have on my data/Example.Json
{
"title": "A",
"lat": 2.323733,
"lon": 64,546465
},
So as soon as I click on the Title, I want to get the title, lat and lon on a new page.
app.modules.ts
import { NgModule, ErrorHandler } from '#angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { MapPage } from '../pages/map/map';
import { ListPage } from '../pages/list/list';
import { DetailPage } from '../pages/detail/detail';
import { Locations } from '../providers/locations';
import { GoogleMaps } from '../providers/google-maps';
import { Connectivity } from '../providers/connectivity';
declare var google: any;
#NgModule({
declarations: [
MyApp,
HomePage,
MapPage,
ListPage,
DetailPage
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage,
MapPage,
ListPage,
DetailPage
],
providers: [{provide: ErrorHandler, useClass: IonicErrorHandler},Locations,GoogleMaps, Connectivity]
})
export class AppModule {}
import { NgModule, ErrorHandler } from '#angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { MapPage } from '../pages/map/map';
import { ListPage } from '../pages/list/list';
import { DetailPage } from '../pages/detail/detail';
import { Locations } from '../providers/locations';
import { GoogleMaps } from '../providers/google-maps';
import { Connectivity } from '../providers/connectivity';
declare var google: any;
#NgModule({
declarations: [
MyApp,
HomePage,
MapPage,
ListPage,
DetailPage
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage,
MapPage,
ListPage,
DetailPage
],
providers: [{provide: ErrorHandler, useClass: IonicErrorHandler},Locations,GoogleMaps, Connectivity]
})
export class AppModule {}
PageA.ts ( list of Data )
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { Locations } from '../../providers/locations';
import { DetailPage } from '../detail/detail';
#Component({
selector: 'page-list',
templateUrl: 'list.html'
})
export class ListPage {
constructor(public navCtrl: NavController, public locations: Locations) {
}
ionViewDidLoad() {
console.log('Test Si marche');
}
viewLocation(event,location) {
this.navCtrl.push(DetailPage, {
"title":location.title,
"longitude":location.longitude
})
}
}
Page B ( where i want to get the detail as soon as i click on something on the list )
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import {NavParams} from "ionic-angular";
import { Locations} from '../../providers/locations';
import { ListPage } from '../list/list';
#Component({
selector: 'page-detail',
templateUrl: 'detail.html',
providers: [ Locations ],
entryComponents:[ ListPage ]
})
export class DetailPage {
title: string
latitude: string
navParams: NavParams
constructor(navParams: NavParams,public navCtrl: NavController) {
this.navParams = navParams
this.title = this.navParams.get('title');
this.latitude = this.navParams.get('latitude');
}
ionViewDidLoad(err) {
console.log(err);
}
goBack() {
this.navCtrl.pop();
}
}
listA.html
<ion-header>
<ion-navbar color="secondary">
<ion-title>List</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list no-lines>
<ion-item *ngFor="let location of locations.data">
<ion-item (click)="viewLocation($event, locations)">{{locations.title}}</ion-item>
<ion-avatar item-left>
<ion-icon name="pin"></ion-icon>
</ion-avatar>
<!--<img src="./src/pics/mus.png"/>-->
<h2>{{location.title}}</h2>
<p>{{location.distance*1.609}} Km</p>
</ion-item>
</ion-list>
</ion-content>
data.json
[
{ "title": "Cat", "longitude": "14,57" },
{ "title": "Bird", "longitude": "17.45" },
{ "title": "Spider", "longitude": "19,12" }
]

If you want to pass data from one page to another, you can either
1) Store your JSON data in SQL format via JSON.stringify(store) and JSON.parse(retrieving) method.
Meaning you stringify the data, before storing inside the SQL table and once retrieved from the next page, you do a JSON.parse to get back your JSON object.
You may want to read up on the following article on how to store data in SQL.
SQL Ionic 2
JSON Parse
JSON Stringify
Or either which, 2) you can make use of navController to "push" data from one page to another. One downside would be if your JSON data is huge, you will have to slowly iterate through.
A simple example would be:
this.navController.push(ThePageNameYouWannaGo, {
firstPassed: "firstData",
secondPassed: "secondData",
thirdPassed: "thirdData",
});
//On the next page (at your constructor),
Constructor(....,NavParams,.....){
this.first = navParams.get("firstPassed");
this.second= navParams.get("secondPassed");
this.third= navParams.get("thirdPassed");
//the value would be stored inside this.first, this.second respectively
For your case, I would recommend method 1 as I have no clue how big is your JSON file and to make your life easier in the future when your JSON file changes.

Related

Why does the function run twice in my every component

I have this problem where i made three different components with routing. The problem is when i open my different components they loop twice at the moment i open them. What is causing this and how can i get rid of it?
Heres one example component which console.log runs twice when i open it.
import { Component, OnInit } from '#angular/core';
import nameData from '../../names/names.json'
interface INames {
name: string,
amount: number
}
const { names } = nameData
#Component({
selector: 'app-four',
templateUrl: './four.html',
styleUrls: ["./four.css"]
})
export class FourComponent {
nameArray: Array<INames> = names
constructor() {
}
hasName(nameParam: any) {
console.log("miksi tämä tulee kaksi kertaa")
return this.nameArray.some(elem => elem.name === nameParam)
}
}
And here is the app.module.ts and app-routing.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { OneComponent } from './requirements/one/one';
import { TwoComponent } from './requirements/two/two';
import { ThreeComponent } from './requirements/three/three';
import { FourComponent } from './requirements/four/four';
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
import { HeaderComponent } from './header/header';
#NgModule({
declarations: [
AppComponent,
OneComponent,
TwoComponent,
ThreeComponent,
FourComponent,
HeaderComponent
],
imports: [
BrowserModule,
AppRoutingModule,
NgbModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app-routing-module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { HomeComponent } from './home/home';
import { FourComponent } from './requirements/four/four';
import { OneComponent } from './requirements/one/one';
import { ThreeComponent } from './requirements/three/three';
import { TwoComponent } from './requirements/two/two';
const appRoutes: Routes = [
{ path: 'home', component: HomeComponent },
{ path: 'one', component: OneComponent },
{ path: 'two', component: TwoComponent },
{ path: 'three', component: ThreeComponent },
{ path: 'four', component: FourComponent }
]
#NgModule({
imports: [RouterModule.forRoot(appRoutes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
I'm really confused why it loops the function as soon as i press the components button?
I do not recommand at all to use function in the HTML template, because they will be called everytime the Angular's change detection runs. Angular isn't able to tell if the result of the function will be different after each modification, si Angular will call the function everytime something change in the UI.
You must store the result of the function in a variable. Angular can check that the reference of the variable hasn't change.
You can read more information about it on this medium.
I recommend that you do the following
public fullName: string;
constructor() {
this.updateName();
}
private updateName(nameParam: any) {
console.log("miksi tämä tulee kaksi kertaa");
this.fullName = this.nameArray.some(elem => elem.name === nameParam);
}
{{ fullName }}

#ngrx/store-devtools - effects called twice

All actions I dispatch in effects are called twice. I already figured out, that this is caused by StoreDevtoolsModule. When I kick StoreDevtoolsModuleout of the app.module.ts my action will be called only once => everything is fine.
Here's my setup:
Angular 6.0.1
"#ngrx/effects": "6.0.0-beta.1",
"#ngrx/entity": "5.2.0",
"#ngrx/router-store": "6.0.0-beta.1",
"#ngrx/store": "6.0.0-beta.1",
"#ngrx/store-devtools": "6.0.0-beta.1",
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { StoreModule, Store, combineReducers, ActionReducerMap, MetaReducer }
from '#ngrx/store';
import { StoreDevtoolsModule } from '#ngrx/store-devtools';
import { EffectsModule } from '#ngrx/effects';
import { EquipmentModule } from './modules/equipment/equipment.module';
const reducers: ActionReducerMap<IAppState> = {
equipments: EquipmentReducer
};
#NgModule({
declarations: [
AppComponent
],
imports : [
BrowserModule,
StoreModule.forRoot(reducers),
StoreDevtoolsModule.instrument({
name: 'EQUIPMENT',
maxAge: 10,
logOnly: true,
}),
EquipmentModule,
EffectsModule.forRoot([]),
]
})
export class AppModule
{}
equipment.module.ts
import { EffectsModule } from '#ngrx/effects';
import { EquipmentEffects } from './equipment.effect';
import { EquipmentMockService } from './equipment.mock';
#NgModule({
imports: [
EffectsModule.forFeature([EquipmentEffects])
],
providers: [
{
provide: 'IEquipmentService',
useClass: EquipmentMockService
},
]
})
export class EquipmentModule {
}
equipment.effect.ts
import { CustomAction } from './../../custom.action';
import { Injectable, Inject } from '#angular/core';
import { Http } from '#angular/http';
import { Actions, Effect, ofType } from '#ngrx/effects';
import { Observable } from 'rxjs/Observable';
import { catchError, map, mergeMap } from 'rxjs/operators';
import { EquipmentActions } from './equipment.action';
import { HttpClient } from '#angular/common/http';
import { Action, State } from '#ngrx/store';
import { of } from 'rxjs/internal/observable/of';
import { EquipmentService } from './equipment.service';
import { IAppState } from '../../app.state';
import { ofTypeWithPayload } from '../../customActionHelper';
#Injectable()
export class EquipmentEffects {
constructor(
private http: HttpClient,
private actions$: Actions,
private readonly state: State<IAppState>,
#Inject('IEquipmentService')
private equipmentService: EquipmentService
) { }
#Effect()
getAllEquipments$: Observable<Action> = this.actions$.pipe(
ofType(EquipmentActions.LOAD_ALL_EQUIPMENTS),
mergeMap(action => {
console.log('here'); <-- This console.log gets called twice!
return this.equipmentService.getAllEquipments().pipe(
map(equipments => ({ type: 'LOAD_ALL_EQUIPMENTS_SUCCESS', payload: equipments })),
catchError(() => of({ type: 'LOAD_ALL_EQUIPMENTS_FAIL' }))
);
}
)
);
Does anyone have an idea?
Thanks

get data from local Json file ionic 3 [duplicate]

This question already has answers here:
No provider for HttpClient
(25 answers)
Closed 5 years ago.
I start a dummy project in Ionic. I try to get data from a local Json file but I have this error :
I don't understand why there is no provider for HttpClient.
For further details, I actually tried to follow this tutorial : https://www.youtube.com/watch?v=vuc4dp0qHSc
How can I fix this error and get the data ?
Versions
Ionic 3.18.0
Angular 5.0.1
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { ErrorHandler, NgModule } from '#angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '#ionic-native/splash-screen';
import { StatusBar } from '#ionic-native/status-bar';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { FirstPage } from '../pages/first/first';
import { CardsDataProvider } from '../providers/cards-data/cards-data';
#NgModule({
declarations: [
MyApp,
HomePage,
FirstPage
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp),
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage,
FirstPage
],
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler},
CardsDataProvider,
]
})
export class AppModule {}
cards-data.ts
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import 'rxjs/add/operator/map';
/*
Generated class for the CardsDataProvider provider.
See https://angular.io/guide/dependency-injection for more info on providers
and Angular DI.
*/
#Injectable()
export class CardsDataProvider {
constructor(public http: HttpClient) {
console.log('Hello CardsDataProvider Provider');
}
getLocalData() {
this.http.get('../assets/data/cards.json').map(res => res.json()).subscribe(data =>
{
console.log(data);
});
}
}
home.ts
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { FirstPage } from '../first/first';
import { CardsDataProvider } from '../../providers/cards-data/cards-data';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public navCtrl: NavController, public CardsService: CardsDataProvider) {
}
openFirstPage() {
this.navCtrl.push(FirstPage);
}
ionViewDidLoad() {
this.CardsService.getLocalData();
}
}
Any help will be appreciated.
You are following an Ionic2 tutorial while using Ionic3 with Angular5.
For Http to work since Ionic 3.0, you need to include HttpClientModule in your imports in app.module.ts.
import {HttpClientModule} from '#angular/common/http';//import
#NgModule({
declarations: [
MyApp,
HomePage,
FirstPage
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp),
HttpClientModule//include here
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage,
FirstPage
],
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler},
CardsDataProvider,
]
})
export class AppModule {}
Also, in your cards-data.ts,
import {Http} from '#angular/common/http';
#Injectable()
export class CardsDataProvider {
constructor(public http: HttpClient) { //change here
console.log('Hello CardsDataProvider Provider');
}
For further changes to go from Ionic 2 to 3 check here. For changes required to go to Angular 5 check here.
A simpler way is to find a more recent tutorial.

Ionic 3 Cordova Native Storage storing modified data

I'm struggling to figure something out. Here's the relevant code.
types.json
{
"types": [
{"name": "Lateral Aids in Navigation", "enabled": false},
{"name": "Canal Structures", "enabled": true},
{"name": "Dockage", "enabled": true},
{"name": "Launch Points", "enabled": true},
{"name": "Landmarks", "enabled": true}
]
}
app.component.ts
import { Component } from '#angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { Http } from '#angular/http';
import { NativeStorage } from '#ionic-native/native-storage';
import { TabsPage } from '../pages/tabs/tabs';
import 'rxjs/add/operator/toPromise';
#Component({
templateUrl: 'app.html'
})
export class CanalGuide {
rootPage:any = TabsPage;
public types;
public places;
constructor(public http: Http, public platform: Platform, public
statusBar: StatusBar, public splashScreen: SplashScreen, public nativeStorage:
NativeStorage) {
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
statusBar.styleDefault();
this.readyTypes();
this.readyPlaces();
splashScreen.hide();
});
}
readyTypes() { return this.http.get('./assets/data/types.json').toPromise().then(
(types) => { this.nativeStorage.setItem('types', types) });
}
readyPlaces() { return this.http.get('./assets/data/canalwatertrail.json').toPromise().then(
(places) => { this.nativeStorage.setItem('places', places) });
}
}
settings.ts
import { Component } from '#angular/core';
import { Http } from '#angular/http';
import { NavController } from 'ionic-angular';
import { NativeStorage } from '#ionic-native/native-storage';
#Component({
selector: 'page-settings',
templateUrl: 'settings.html'
})
export class SettingsPage {
public toggles;
public types;
constructor(private http: Http, public navCtrl: NavController, public
nativeStorage: NativeStorage) {}
ionViewDidEnter() {
this.nativeStorage.getItem('types').then((data) => {
this.toggles = JSON.parse(data._body)
console.log(this.toggles);
});
}
// The relevant code
ionViewWillLeave() {
this.nativeStorage.setItem('types', this.toggles);
console.log(this.nativeStorage.getItem('types'));
}
}
settings.html
<ion-header>
<ion-navbar>
<ion-title>
Settings
</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list no-lines *ngIf="toggles">
<ion-list-header>Atlas Filters</ion-list-header>
<ion-item *ngFor="let type of toggles.types">
<ion-label>{{type.name}} - {{type.enabled}}</ion-label>
<ion-toggle [(ngModel)]="type.enabled"></ion-toggle>
</ion-item>
</ion-list>
My problem is this - The console.log() in ionViewWillLeave returns the following:
t {__zone_symbol__state: null, __zone_symbol__value: Array(0)}
__zone_symbol__state
:
true
__zone_symbol__value
:
{types: Array(5)}
__proto__
:
Object
Now in the ionicViewWillLeave function, how do I properly save the modifications to types.json back into Native Storage so it can be used again on a different page with nativeStorage.getItem? This seemingly simple function has been driving me crazy for a while now.
Please take a look at the documentation: https://ionicframework.com/docs/native/native-storage/
getItem and setItem return a promise, so you can't simply log it. You have to wait until the promise is resolved.
this.nativeStorage.setItem('types', {property: 'value', anotherProperty: 'anotherValue'})
.then(
() => console.log('Stored item!'),
error => console.error('Error storing item', error)
);
or
this.nativeStorage.getItem('types')
.then(
data => console.log(data),
error => console.error(error)
);

ngx-translation issue with ionic 3 app

ngx translation with ionic 3 app not working for me. below is my code:
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { ErrorHandler, NgModule } from '#angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { HttpModule,Http } from '#angular/http';
import { IonicStorageModule } from '#ionic/storage';
import { TranslateModule, TranslateLoader } from '#ngx-translate/core';
import { TranslateHttpLoader } from '#ngx-translate/http-loader';
import { MyApp } from './app.component';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
export function createTranslateLoader(http: Http) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
#NgModule({
declarations: [
MyApp
],
imports: [
BrowserModule,
HttpModule,
IonicStorageModule.forRoot(),
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [Http]
}
}),
IonicModule.forRoot(MyApp),
],
bootstrap: [IonicApp],
entryComponents: [
MyApp
],
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler},
]
})
export class AppModule {}
app.component.ts
import { Component, ViewChild } from '#angular/core';
import { Nav, Platform } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { Storage } from '#ionic/storage';
import { TranslateService } from '#ngx-translate/core';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
#ViewChild(Nav) nav: Nav;
public rootPage: any;
constructor(public platform: Platform,
public statusBar: StatusBar,
public splashScreen: SplashScreen,
public storage: Storage,
public translate: TranslateService) {
this.storage.get('AppLangcode')
.then((AppLangcode) => {
if(AppLangcode==null){
translate.setDefaultLang('en');
}else{
translate.setDefaultLang(AppLangcode);
}
})
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
this.menu.swipeEnable(false);
});
}
}
In above file i am checking storage preference in local db and then set it to default language on load application.
My RootPage home.module.ts
import { NgModule } from '#angular/core';
import { IonicPageModule } from 'ionic-angular';
import { HomePage } from './home';
import { TranslateModule } from '#ngx-translate/core';
#NgModule({
declarations: [
HomePage,
],
imports: [
IonicPageModule.forChild(HomePage),
TranslateModule.forChild()
],
exports: [
HomePage
]
})
export class HomePageModule {}
home.ts
import { Component} from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Storage } from '#ionic/storage';
import { TranslateService } from '#ngx-translate/core';
#IonicPage()
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public navCtrl: NavController,
public navParams: NavParams,
public storage: Storage,
public translate: TranslateService,) {
}
ionViewDidLoad() {
//console.log('ionViewDidLoad HomePagePage');
}
}
home.html
<ion-header>
<ion-navbar color='navbarColor'>
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title><img src="assets/icon/logo.png" alt="Ionic logo"></ion-title>
</ion-navbar>
</ion-header>
<ion-content class="grid-basic-page">
<ion-grid>
<ion-row>
<ion-col (click)="openPage('QuickBookPage');">
<div><img src="assets/icon/icon-book-cylinder.png">{{"quick_book_pay" | translate}}</div>
</ion-col>
<ion-col (click)="openPage('RefilHistoryPage');">
<div><img src="assets/icon/icon-quickpay.png">{{"refil_history" | translate}}</div>
</ion-col>
</ion-row>
<ion-row>
<ion-col (click)="openPage('ServicesPage');">
<div><img src="assets/icon/icon-mechanic.png">{{"service_request" | translate}}</div>
</ion-col>
<ion-col>
<button [disabled]="!clickhandle" (click)="emergencyCall();"><img src="assets/icon/icon-emergency.png">{{"emergency_helpline" | translate}}</button>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
Side Menu Page language.ts
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams,Events } from 'ionic-angular';
import { NgForm,FormBuilder, FormGroup, Validators } from '#angular/forms';
import { TranslateService } from '#ngx-translate/core';
import { Storage } from '#ionic/storage';
#IonicPage()
#Component({
selector: 'page-language',
templateUrl: 'language.html',
})
export class LanguagePage {
public langform:FormGroup;
public langcod:string;
constructor(public navCtrl: NavController,
public navParams: NavParams,
public formBuilder: FormBuilder,
public translate: TranslateService,
public storage: Storage) {
this.storage.get('AppLangcode')
.then((AppLangcode) => {
if(AppLangcode==null){
this.langcod = 'en';
this.langform.get('langcode').setValue(this.langcod);
}else{
this.langcod = AppLangcode;
this.langform.get('langcode').setValue(this.langcod);
}
})
this.langform = formBuilder.group({
langcode: [this.langcod, Validators.required]
});
}
langselect(form: NgForm){
let langselcode = this.langform.value.langcode;
this.storage.set('AppLangcode', langselcode);
this.translate.setDefaultLang(langselcode);
this.translate.use(langselcode);
}
}
language.module.ts
import { NgModule } from '#angular/core';
import { IonicPageModule } from 'ionic-angular';
import { LanguagePage } from './language';
import { TranslateModule } from '#ngx-translate/core';
#NgModule({
declarations: [
LanguagePage,
],
imports: [
IonicPageModule.forChild(LanguagePage),
TranslateModule.forChild()
],
exports: [
LanguagePage
]
})
export class LanguagePageModule {}
language.html
<ion-header>
<ion-navbar color='navbarColor'>
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title><img src="assets/icon/logo.png" alt="Ionic logo"></ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<form [formGroup]="langform" (submit)="langselect($event)">
<ion-list radio-group formControlName="langcode">
<ion-row responsive-sm>
<ion-col col-6>
<ion-item>
<ion-label>{{"english" | translate}}</ion-label>
<ion-radio value="en" checked></ion-radio>
</ion-item>
<ion-item>
<ion-label>{{"hindi" | translate}}</ion-label>
<ion-radio value="hi"></ion-radio>
</ion-item>
</ion-col>
</ion-row>
</ion-list>
<ion-row responsive-sm>
<ion-col>
<button ion-button block type="submit" [disabled]="!langform.valid">
Submit
</button>
</ion-col>
</ion-row>
</form>
</ion-content>
en.json
{
"english" : "English",
"hindi" : "हिंदी",
"quick_book_pay":"Quick Book & Pay",
"refil_history":"Refill History",
"service_request":"Service Request",
"emergency_helpline":"Emergency Helpline"
}
hi.json
{
"english" : "English",
"hindi" : "हिंदी",
"quick_book_pay":"त्वरित बुक और भुगतान करें",
"refil_history":"रीफिल इतिहास",
"service_request":"सेवा अनुरोध",
"emergency_helpline":"आपातकालीन हेल्पलाइन"
}
On change language it show keys instead translation. Please let me know what wrong i am doing ?
i have updated my language module and this worked for me, not sure if this is right way but it's worked.
import { NgModule } from '#angular/core';
import { IonicPageModule } from 'ionic-angular';
import { LanguagePage } from './language';
import { TranslateModule, TranslateLoader } from '#ngx-translate/core';
import { TranslateHttpLoader } from '#ngx-translate/http-loader';
import { HttpModule,Http } from '#angular/http';
export function createTranslateLoader(http: Http) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
#NgModule({
declarations: [
LanguagePage,
],
imports: [
IonicPageModule.forChild(LanguagePage),
TranslateModule.forChild({
loader: {
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [Http]
}
})
],
exports: [
LanguagePage
]
})
export class LanguagePageModule {}
i have added loader for child and export TranslateHttpLoader in language.module.ts
language.ts
langselect(form: NgForm){
let langselcode = this.langform.value.langcode;
this.storage.set('AppLangcode', langselcode);
this.translate.use(langselcode);
}
I spent hours to get it working on Ionic 3. Finally I had to add HttpClientModule to the import section of app.module.ts. Hope that helps.
[2]: Use HttpClient instead of Http
[3]: Add HttpClientModule
[4]: Use HttpClient instead of Http
src/app/app.module.ts:
import {HttpClient, HttpClientModule} from "#angular/common/http";
import {HttpModule, RequestOptions, XHRBackend} from '#angular/http';
import {TranslateModule, TranslateLoader} from '#ngx-translate/core';
import {TranslateHttpLoader} from '#ngx-translate/http-loader';
export function createTranslateLoader(http: HttpClient [2]) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
#NgModule({
...
imports: [
BrowserModule,
HttpModule,
HttpClientModule [2],
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: createTranslateLoader,
deps: [HttpClient] [3]
}
...
...
}),
src/pages/[your-page]/[your-page].module.ts
imports: [
IonicPageModule.forChild(LoginPage),
TranslateModule.forChild(),
],
I had the same issue and managed to fix it. I'm lazy loading the pages and the problem occurred when I try to change the language from a component. He's how I fixed it.
app.component.ts
this.translateService.addLangs(['en', 'lk']);
this.translateService.setDefaultLang("en");
this.eventProvider.currentLang.subscribe(lang => {
this.translateService.use(lang);
});
event-provider.ts
import { EventEmitter } from '#angular/core';
export class EventProvider {
public currentLang: EventEmitter<string> = new EventEmitter();
setLang(val) {
this.currentLang.emit(val);
}
}
Import event-provider.ts to App Module and include in providers.
Now you can import it to any component where you need to change the language and emmit the value.
custom-header-component.ts
setLanguage(val:string) {
this.eventProvider.setLang(val);
}
Finally, i a solve this issue by using HttpClientModule in the import section of app.module.ts. maybe it helps.
First: Import HttpClientModule
Second: Use HttpClient instead of Http.
So, the code is as follow: app.module.ts
import { NgModule } from '#angular/core';
import { IonicPageModule } from 'ionic-angular';
import { HomePage } from './home';
//translate related imports
import { TranslateModule, TranslateLoader } from '#ngx-translate/core';
import { TranslateHttpLoader } from '#ngx-translate/http-loader';
import { HttpClientModule, HttpClient } from '#angular/common/http';
#NgModule({
declarations: [
HomePage,
],
imports: [
IonicPageModule.forChild(HomePage),
HttpClientModule
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [HttpClient ]
}
})
],
exports: [
HomePage
]
})
export class HomePageModule {}
export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
In app.component.ts add this line in constructor.
import {TranslateService} from '#ngx-translate/core';
...
translate.setDefaultLang('en');//So English language set
And then you have to create two JSON files in ./assets/i18n/ path.
en.JSON
{
"title": "Translation demo",
"text": "This is a simple demonstration app for {{value}}"
}
Then use in your app with PIPE filter like this.
<h1>{{'title' | translate}}</h1>
OR
<h1 [translate]="'title'"></h1>
We can also pass a parameter.
<h1>{{'text' | translate:{'value':'ngx-translate'} }}</h1>
OR
<h1 [translate]="'text'" [translateParams]="{value: 'ngx-translate'}"></h1>