trasnlate.use() gives me this error: {code:2, source:Native, exception:null} #87
Description
Current behavior
when ı build my app and run on my real android device, (first page is login page) at first run, translate.use() gives me this error: {code:2, source:Native, exception:null}. if ı need to fix this, ı need to login first, ı login and redirect to inside page(root changing), then ı close app and reopen again, then my translate.use works fine. if I dont login (dont change root), even if ı close and open app again and again(without changing root), translate.use() never works.
And if ı install app via terminal to my real device with this code: "ionic cordova run android --device", it just works fine, deosnt give me any error at all... but after ı build it with "ionic cordova build android --release" and make app and install it to my device, it gives me this error ı mentioned
And it just works on web without any problem
Expected behavior
How do you think that we should fix this?
Minimal reproduction of the problem with instructions
my app.module.ts:
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import {HttpClient, HttpClientModule,HTTP_INTERCEPTORS} from '@angular/common/http'
import {HTTP} from '@ionic-native/http/ngx'
import { TokenInterceptorService } from './core/interceptors/TokenInterceptor.service';
import { NativeStorage } from '@ionic-native/native-storage/ngx';
import { IonicStorageModule } from '@ionic/storage';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {MatDialogModule} from '@angular/material/dialog';
import {MatButtonModule} from '@angular/material/button';
import {MatExpansionModule} from '@angular/material/expansion';
import {MatSelectModule} from '@angular/material/select';
import { MatCommonModule } from '@angular/material/core';
import {MatInputModule} from '@angular/material/input';
import { FormsModule } from '@angular/forms';
import {MatRadioModule} from '@angular/material/radio';
import {MatCheckboxModule} from '@angular/material/checkbox';
import {MatTabsModule} from '@angular/material/tabs';
import {MatTableModule} from '@angular/material/table';
import { DatePipe } from '@angular/common';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { HousekeepingrackComponent } from './core/components/alerts/housekeepingrack/housekeepingrack/housekeepingrack.component';
import { HousekeepingComponent } from './core/components/alerts/housekeeping/housekeeping.component';
import { SecurityComponent } from './core/components/alerts/security/security.component';
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
import { IonicSelectableModule } from 'ionic-selectable';
import { EventService } from './core/services/event/Event.service';
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, "./assets/i18n/", ".json");
}
@NgModule({
declarations: [AppComponent,HousekeepingrackComponent,HousekeepingComponent,SecurityComponent],
entryComponents: [],
schemas:[CUSTOM_ELEMENTS_SCHEMA],
imports: [
BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
HttpClientModule,
IonicStorageModule.forRoot(),
BrowserAnimationsModule,
MatDialogModule,
MatButtonModule,
MatExpansionModule,
MatSelectModule,
MatCommonModule,
MatInputModule,
FormsModule,
MatRadioModule,
MatCheckboxModule,
MatTabsModule,
MatTableModule,
IonicSelectableModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (HttpLoaderFactory),
deps: [HttpClient]
}
})
],
providers: [
StatusBar,
SplashScreen,
EventService,
TranslateService,
DatePipe,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
HTTP,
{
provide:HTTP_INTERCEPTORS,
useClass:TokenInterceptorService,
multi:true
},
NativeStorage
],
bootstrap: [AppComponent]
})
export class AppModule {}
my app-rooting.module.ts:
import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { LoginPageModule } from './pages/login/login.module';
const routes: Routes = [
{
path: 'login',
loadChildren: () => import('./pages/login/login.module').then( m => m.LoginPageModule),
},
{
path: 'traces/tracelist',
loadChildren: () => import('./pages/traces/traces.module').then( m => m.TracesPageModule)
},
{
path: 'housekeeping/housekeepingrack',
loadChildren: () => import('./pages/housekeepingrack/housekeepingrack.module').then( m => m.HousekeepingrackPageModule)
},
{
path: 'housekeeping/rooms',
loadChildren: () => import('./pages/housekeeping/housekeeping.module').then( m => m.HousekeepingPageModule)
},
{
path: 'operation/security',
loadChildren: () => import('./pages/security/security.module').then( m => m.SecurityPageModule)
},
{
path: 'profile/search',
loadChildren: () => import('./pages/profile/profile.module').then( m => m.ProfilePageModule)
},
{
path: 'profilemodal',
loadChildren: () => import('./modalpages/profilemodal/profilemodal.module').then( m => m.ProfilemodalPageModule)
},
{
path: 'main/dashboard',
loadChildren: () => import('./pages/dashboard/dashboard.module').then( m => m.DashboardPageModule)
},
{
path: 'guest-search',
loadChildren: () => import('./modalpages/guest-search/guest-search.module').then( m => m.GuestSearchPageModule)
},
{
path: 'activities',
loadChildren: () => import('./pages/activities/activities.module').then( m => m.ActivitiesPageModule)
},
{
path: 'reservation',
loadChildren: () => import('./modalpages/reservation/reservation.module').then( m => m.ReservationPageModule)
},
{
path: 'alakart-modal',
loadChildren: () => import('./pages/alakart-modal/alakart-modal.module').then( m => m.AlakartModalPageModule)
},
{
path: 'iframe',
loadChildren: () => import('./modalpages/iframe/iframe.module').then( m => m.IframePageModule)
},
{
path: 'options',
loadChildren: () => import('./pages/options/options.module').then( m => m.OptionsPageModule)
},
{
path: 'accounting',
loadChildren: () => import('./pages/accounting/accounting.module').then( m => m.AccountingPageModule)
},
//en sonda olması lazım, wildcard url requests için
{ path: '**', loadChildren: () => import('./pages/login/login.module').then( m => m.LoginPageModule) }
];
@NgModule({
imports: [
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
],
exports: [RouterModule]
})
export class AppRoutingModule {}
my app.component.ts:
import { Component, OnInit } from '@angular/core';
import { Platform, ToastController } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { EventService } from './core/services/event/Event.service';
import { HttpService } from './core/services/http/http.service';
import { MenuService } from './core/services/menu/menu.service';
import { CompanyService } from './core/services/company/company.service';
import { StorageService } from './core/services/storage/storage.service';
import { Router } from '@angular/router';
import { TranslatingService } from './core/services/translate/translate.service';
import { TranslateService } from '@ngx-translate/core';
import { LoadingService } from './core/services/loading/loading.service';
import { SharedService } from './core/services/shared/shared.service';
import { ThemeService } from './core/services/theme.service';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss']
})
export class AppComponent implements OnInit {
public selectedIndex = 0;
public userName: string = "";
public lastCompanyName: string = "";
public appPages = [];
public companies = [];
public userInfo: any;
public labels = ['Family', 'Friends', 'Notes', 'Work', 'Travel', 'Reminders'];
menuList: any[];
deviceLanguage: any;
isFromLogin: Boolean = false;
loaderInstance: any;
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private loading: LoadingService,
private eventService: EventService,
private httpService: HttpService,
private menuService: MenuService,
private router: Router,
private sharedService: SharedService,
private translatingService: TranslatingService,
private angularTranslateService: TranslateService,
private companyService: CompanyService,
private storageService: StorageService,
private toastCtrl: ToastController,
private themeService: ThemeService,
private shared: SharedService) {
this.platform.ready().then(res => {
// alert('app comp constractor')
//alert("app constructor içine girdi")
this.angularTranslateService.use('tr').toPromise().then(res=>{
alert('başarılı dil değişimi: '+JSON.stringify(res))
}).catch(err=>{
alert('alert: '+JSON.stringify(err))
})
this.initializeApp();
this.storageService.getItem("themeColor").then(res => {
if (res) {
} else {
this.storageService.setItem("themeColor", "#8f074d")
}
this.themeService.setTheme()
}).catch(err => {
//alert('themeColor: ' + JSON.stringify(err))
this.storageService.setItem("themeColor", "#8f074d")
})
this.shared.loaderObservable.subscribe(res => {
this.loaderInstance = res
})
this.eventService.isLoggedInObserved.subscribe(data => {
if (data) {
return this.FillCurrentAppPages(data.isLoggedIn).then(res => {
return res
}).catch(err => {
console.log("FillCurrentAppPages error", err)
});
}
});
this.storageService.getItem("appPages").then(appPages => {
this.appPages = appPages
}).catch(err => { })
this.storageService.getItem("GetAccountAndCompanyInfo").then(GetAccountAndCompanyInfo => {
// alert("GetAccountAndCompanyInfo cache "+ JSON.stringify(GetAccountAndCompanyInfo))
if (GetAccountAndCompanyInfo) {
this.userInfo = GetAccountAndCompanyInfo.UserInfo;
this.storageService.setItem('userInfo', this.userInfo);
this.IsHotelApiWorking();
this.userName = GetAccountAndCompanyInfo.UserInfo.UserName;
this.companies = GetAccountAndCompanyInfo.CompaniesAccounts;
this.storageService.setItem("companies", this.companies)
this.lastCompanyName = this.GetLastCompanyName(this.companies, GetAccountAndCompanyInfo.UserInfo.LastCompanyId);
GetAccountAndCompanyInfo.SidebarNavigations.forEach(nav => {
nav.submenu.forEach(sub => {
this.menuList.forEach(menu => {
if (menu.target == sub.target) {
this.appPages.push({ title: menu.name, url: menu.url, icon: menu.icon })
}
});
});
});
}
}).catch(err => { })
})
}
// ngOnDestroy() {
// console.log('destroy app comp');
// // this.onDestroy.next();
// }
initializeApp() {
alert('app comp initApp()')
//alert("initializeApp içine girdi")
//cihazın dilini bulur ve çevirici servise ilgili parametreleri gönderip json dil dosyalarını kullanır
var deviceLangSTR = this.angularTranslateService.getBrowserLang()
//alert('deviceLangSTR ' + JSON.stringify(deviceLangSTR))
this.deviceLanguage = this.translatingService.languageSelectorFromStringToNumber(deviceLangSTR)
//alert('this.deviceLanguage döndü ' + JSON.stringify(this.deviceLanguage))
// alert("dil: "+JSON.stringify(this.deviceLanguage))
this.storageService.setItem("LangID", this.deviceLanguage)
this.statusBar.styleDefault();
this.storageService.initializePermissions()
this.router.navigate(['/login'])
// alert('device lang str : ' + JSON.stringify(deviceLangSTR) + " device lang int " + JSON.stringify(this.deviceLanguage))
// this.translatingService.switchLanguage(this.deviceLanguage).then(res => {
// this.statusBar.styleDefault();
// this.storageService.initializePermissions()
// this.router.navigate(['/login']).then(res=>{
// alert('alert: '+JSON.stringify(res))
// }).catch(err=>{
// alert('alert: '+JSON.stringify(err))
// })
// }).catch(err => {
// this.translatingService.switchLanguage(this.deviceLanguage).then(res => {
// this.statusBar.styleDefault();
// this.storageService.initializePermissions()
// })
// })
}
GetAccountAndCompanyInfo(): Promise<any> {
return this.httpService.Post('v1/SednaMobileB2B/GetAccountAndCompanyInfo', {}).then(GetAccountAndCompanyInforesponse => {
// alert("GetAccountAndCompanyInfo api istek "+ JSON.stringify(GetAccountAndCompanyInforesponse))
if (GetAccountAndCompanyInforesponse) {
this.storageService.setItem("GetAccountAndCompanyInfo", GetAccountAndCompanyInforesponse)
this.userInfo = GetAccountAndCompanyInforesponse.UserInfo;
this.storageService.setItem('userInfo', this.userInfo);
this.IsHotelApiWorking();
this.userName = GetAccountAndCompanyInforesponse.UserInfo.UserName;
this.companies = GetAccountAndCompanyInforesponse.CompaniesAccounts;
this.storageService.setItem("companies", this.companies)
this.lastCompanyName = this.GetLastCompanyName(this.companies, GetAccountAndCompanyInforesponse.UserInfo.LastCompanyId);
const findPage = this.appPages.find(x => x.title == 'Dashboard');
if (!findPage) {
this.appPages.push({ title: 'Dashboard', url: '/main/dashboard', icon: 'home' })
}
GetAccountAndCompanyInforesponse.SidebarNavigations.forEach(dashboardPermissions => {
if (dashboardPermissions.title == "b2bdashboard") {
dashboardPermissions.submenu.forEach(element => {
this.storageService.SetPagePermissionsForDashboardPage(element.target);
});
}
})
GetAccountAndCompanyInforesponse.SidebarNavigations.forEach(nav => {
nav.submenu.forEach(sub => {
this.menuList.forEach(menu => {
if (menu.target == sub.target) {
if (menu.target == "bms.mobileb2b.dashboard") {
console.log(menu)
} else {
this.appPages.push({ title: menu.name, url: menu.url, icon: menu.icon })
this.storageService.SetPagePermissions(menu.target);
}
}
});
});
});
this.appPages.push({ title: 'Ayarlar', url: '/options', icon: 'settings' });
// this.appPages.push({ title: 'Accounting', url: '/accounting', icon: 'exit' })
this.appPages.push({ title: 'Çıkış Yap', url: '', icon: 'exit', type: 'exit' })
this.storageService.setItem("appPages", this.appPages)
this.router.navigateByUrl('/main/dashboard');
if (this.loaderInstance) {
console.log("loader instance: ", this.loaderInstance)
this.loaderInstance.loadingController.ctrl.dismiss()
}
this.eventService.publish({ name: 'refreshdashboard' });
return GetAccountAndCompanyInforesponse
}
}).catch(err => {
return err
if (this.loaderInstance) {
console.log("loader instance: ", this.loaderInstance)
this.loaderInstance.loadingController.ctrl.dismiss()
}
alert("getAccountAndCompanyInfos error " + JSON.stringify(err))
})
}
FillCurrentAppPages(isLoggedIn: boolean): Promise<any> {
if (isLoggedIn) {
this.appPages = [];
this.menuList = this.menuService.GetMobileMenuList();
return this.GetAccountAndCompanyInfo().then(res => {
return res
}).catch(err => {
alert("fill current hata: " + JSON.stringify(err))
return err
})
}
}
GetLastCompanyName(companies: any, lastCompanyId: any): string {
var companyName: string = "Not Found";
companies.forEach(company => {
company.Companies.forEach(subCompany => {
if (subCompany.Id == lastCompanyId) {
companyName = subCompany.CompanyName;
return;
}
})
});
this.storageService.setItem("lastCompanyName", companyName)
this.sharedService.updateLastCompanyName(true);
return companyName;
}
changeCompany(subCompany): void {
this.loading.show().then(res => {
this.companyService.ChangeActiveCompany(subCompany.Id).then(response => {
this.storageService.getItem('token').then(token => {
this.httpService.Sedna360RefreshToken(token.refresh_token).then(refreshResponse => {
this.storageService.setItem('token', refreshResponse);
this.FillCurrentAppPages(true).then(res => {
this.loading.hide()
});
}).catch(err => {
alert("change company refresh token err: " + JSON.stringify(err))
});
}).catch(err => {
alert('token change company: ' + JSON.stringify(err))
})
});
})
}
async IsHotelApiWorking() {
this.storageService.getItem('userInfo').then(async userResponse => {
// alert("isotelapiworking "+ JSON.stringify(userResponse))
if (userResponse.IsHotelApiWorking == false) {
const toast = await this.toastCtrl.create({
message: 'Hotel bağlantı Hatası',
duration: 2000,
cssClass: 'failToast',
position: 'top'
});
toast.present();
}
}).catch(err => {
alert('this.storageService.getItem("userInfo"): ' + JSON.stringify(err))
});
}
selectedIndexFunc(i) {
this.selectedIndex = i;
var selectedMenu = this.appPages[i];
console.log(selectedMenu)
if (selectedMenu.type) {
if (selectedMenu.type == 'exit') {
this.storageService.removeAll()
this.storageService.initializePermissions()
}
}
}
ngOnInit() {
console.log("Buraya ne zaman geliyor.")
const path = window.location.pathname.split('folder/')[1];
if (path !== undefined) {
this.selectedIndex = this.appPages.findIndex(page => page.title.toLowerCase() === path.toLowerCase());
console.log("selected index app comp ", this.selectedIndex)
}
}
}
my angular.json file:
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"defaultProject": "app",
"newProjectRoot": "projects",
"projects": {
"app": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "www",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"assets": [
{
"glob": "**/*",
"input": "src/assets",
"output": "assets"
},
{
"glob": "**/*.svg",
"input": "node_modules/ionicons/dist/ionicons/svg",
"output": "./svg"
}
],
"styles": [
{
"input": "src/theme/variables.scss"
},
{
"input": "src/global.scss"
}
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
},
"ci": {
"progress": false
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "app:build"
},
"configurations": {
"production": {
"browserTarget": "app:build:production"
},
"ci": {
"progress": false
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "app:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"styles": [],
"scripts": [],
"assets": [
{
"glob": "favicon.ico",
"input": "src/",
"output": "/"
},
{
"glob": "**/*",
"input": "src/assets",
"output": "/assets"
}
]
},
"configurations": {
"ci": {
"progress": false,
"watch": false
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude": ["**/node_modules/**"]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "app:serve"
},
"configurations": {
"production": {
"devServerTarget": "app:serve:production"
},
"ci": {
"devServerTarget": "app:serve:ci"
}
}
},
"ionic-cordova-build": {
"builder": "@ionic/angular-toolkit:cordova-build",
"options": {
"browserTarget": "app:build"
},
"configurations": {
"production": {
"browserTarget": "app:build:production"
}
}
},
"ionic-cordova-serve": {
"builder": "@ionic/angular-toolkit:cordova-serve",
"options": {
"cordovaBuildTarget": "app:ionic-cordova-build",
"devServerTarget": "app:serve"
},
"configurations": {
"production": {
"cordovaBuildTarget": "app:ionic-cordova-build:production",
"devServerTarget": "app:serve:production"
}
}
}
}
}
},
"cli": {
"defaultCollection": "@ionic/angular-toolkit"
},
"schematics": {
"@ionic/angular-toolkit:component": {
"styleext": "scss"
},
"@ionic/angular-toolkit:page": {
"styleext": "scss"
}
}
}
Environment
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
"@angular/cdk": "^10.2.7",
"@angular/common": "~10.0.0",
"@angular/core": "~10.0.0",
For Tooling issues:
- Node version: 14.15.4
- Platform: real android device
Others: