On my Ionic app the ngx-translate is giving me this message on console:
.... assets/i18n/.json 404 (Not Found)
With another details on HttpErrorResponse
So my app on BROWSER keeps giving this error, and when I build to use on phone it just trigger an alert message with this error and closes the app
My Setup:
Android.
"cordova-plugin-crosswalk-webview": "^2.4.0" <- LITE
"#ngx-translate/core": "^9.1.1",
"#ngx-translate/http-loader": "^2.0.1",
Ionic 3
Here's my app.module.ts
import { HttpClientModule, HttpClient } from '#angular/common/http';
import { TranslateModule, TranslateLoader } from '#ngx-translate/core';
import { TranslateHttpLoader } from '#ngx-translate/http-loader';
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, '../assets/i18n/', '.json');
}
imports: [
BrowserModule,
IonicModule.forRoot(MyApp),
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
})
I saw other users having issues with the
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, '../assets/i18n/', '.json');
Changing it to just Http instead of HttpClient, but was no use for me. Typescript tells me the http has to be HttpClient type.
This is my app.component.ts
import { TranslateService } from '#ngx-translate/core';
.
.
.
constructor(
private translateService: TranslateService,
public platform: Platform,
public statusBar: StatusBar,
public splashScreen: SplashScreen
) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
// this.setAppTranslation();
this.translateService.addLangs(["en", "pt"]);
this.translateService.setDefaultLang('en');
this.translateService.use('en');
});
}
I've follow this tutorial to apply the function to my app:
https://www.gajotres.net/ionic-2-internationalize-and-localize-your-app-with-angular-2/
Can anyone help me at least understand?
My assets/i18n folder has 2 files:
en.json
pt.json
I've had that problem before, try these two things:
Change your loader to this (as #Mohsen said):
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
And your useFactory to this:
useFactory: (HttpLoaderFactory)
IMPORTANT: Make sure your assets folder is at this level:
/ src / assets /
SEARCH
key: "loadUrl",
value: function(t, e) {
var n = this;
THEN ADD,
if (t !== undefined)
t = t.replace("../../../app-assets/", "../../../control/app-assets/");
Related
I've written a provider to help track network connectivity using the Native Network plugin:
import { Injectable } from '#angular/core';
import { Network } from '#ionic-native/network';
import { Platform } from 'ionic-angular';
#Injectable()
export class Connectivity {
public online: boolean = false;
constructor(private network: Network) {
this.network.onDisconnect().subscribe(() => {
console.log('Network offline');
this.online = false;
});
this.network.onConnect().subscribe(() => {
this.online = true;
console.log('Network online');
});
});
}
}
I've installed the relevent plugins (package.json):
"cordova-plugin-network-information": "^2.0.1",
...
"#ionic-native/network": "^4.7.0",
And I've included my provider in my app.module.ts:
providers: [
Network,
StatusBar,
SplashScreen,
Connectivity,
{provide: ErrorHandler, useClass: IonicErrorHandler}
]
Yet, when I run the app in the browser, neither of the observables fire. If I try print: console.log(this.network.type) in the provider constructor, it just prints null.
The answer here is that the native network plugin doesn't work in the browser. Even though it has "browser" listed as a supported platform:
It is referring to the Cordova Browser which is different to a web browser. I found this out after discussion on the Ionic Slack channel.
You need to instead write a Provider that:
Detects platform
If on a native device, use the native network plugin
If in a browser, use the browser API
For others with the same problem:
Here is some clarification on why you have two different APIs available
Here is an example of a provider that uses a variety of approaches for finding location (this isn't the same as my question, but is similar in the solution as it uses a browser API as well as the Ionic Native API)
In my application I use "cordova-plugin-network-information": "^ 2.0.1"
and "#ionic-native / network": "^ 4.6.0"
I can share the same service I use. this is currently working
'# angel / core' import {Injectable};
From the '# Ionic-native / network' resource {Network};
import { Injectable } from '#angular/core';
import { Network } from '#ionic-native/network';
#Injectable()
export class NetworkProvider {
constructor(private _network: Network) { }
isConnectInternet() {
return this._network.onConnect();
}
isDisconnect() {
return this._network.onDisconnect();
}
enter code here
connectionType() {
if (this._network.type == 'none' ) {
return false;
} else {
return true;
}
}
}
I am using this service into my project which is on following environment
cli packages:
#ionic/cli-utils : 1.19.2
ionic (Ionic CLI) : 3.20.0
global packages:
cordova (Cordova CLI) : 8.0.0
this is my provider file, network.ts.
import { Functions } from './../functions';
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Network } from '#ionic-native/network';
import { Events } from 'ionic-angular';
/*
Generated class for the NetworkProvider provider.
See https://angular.io/guide/dependency-injection for more info on providers
and Angular DI.
*/
export enum ConnectionStatusEnum {
Online,
Offline
}
#Injectable()
export class NetworkProvider {
previousStatus;
constructor(public functions:Functions,
public network: Network,
public eventCtrl: Events) {
this.previousStatus = ConnectionStatusEnum.Online;
}
public initializeNetworkEvents(): void {
this.network.onDisconnect().subscribe(() => {
if (this.previousStatus === ConnectionStatusEnum.Online) {
this.eventCtrl.publish('network:offline');
}
this.previousStatus = ConnectionStatusEnum.Offline;
});
this.network.onConnect().subscribe(() => {
if (this.previousStatus === ConnectionStatusEnum.Offline) {
this.eventCtrl.publish('network:online');
}
this.previousStatus = ConnectionStatusEnum.Online;
});
}
make sure that you are running
ionic cordova run browser
not
ionic serve
I'm getting the error NullInjectorError: No provider for NavController. I searched for it and I know I shouldn't inject it into the appcomponent. I'm not doing so, but I still get the error. I have appComponent which is my rootcomponent. As startpage i'm setting my StartPage. In this StartPage i'm injecting the What am I doing wrong?
AppComponent template:
<ion-nav #content [root]="rootPage"></ion-nav>
AppComponent:
export class AppComponent {
rootPage: any = StartPage; //Setting my start page
constructor(
private platform: Platform,
private statusBar: StatusBar,
private splashScreen: SplashScreen) {
}
ionViewDidLoad() {
this.platform.ready().then(() => {
this.statusBar.styleBlackTranslucent();
this.splashScreen.hide();
});
}
}
StartPage:
export class StartPage {
constructor(private navController: NavController){
}
signin(){
this.navController.push(LoginPage);
}
signup(){
this.navController.push(SignupPage);
}
}
Try to import NavCtrl at the top of the file, where you need it (at the top of the StartPage?):
import { NavController } from 'ionic-angular';
And adding it into constructor, as you did, should be enough.
I am trying to execute file transfer from a Flask server to an Ionic3 application. Basically, what I want to do is send a .vcf file from the server to the application to them be read and displayed in the application. The application does not need to store the file in any form of persistent memory.
When I try to do this, I get a ton of error. The one I am encountering right now is:
Encountered undefined provider! Usually this means you have circular dependencies (might be caused by using 'barrel' index.ts files.
I tried making a whole separate provider file for file-transfer but that just gave me other errors. Currently, my .ts file that is throwing the error is as follows:
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Transfer, TransferObject } from '#ionic-native/file-transfer';
import { File } from '#ionic-native/file';
#IonicPage()
#Component({
selector: 'page-quiz',
templateUrl: 'quiz.html',
providers: [Transfer, TransferObject, File]
})
export class QuizPage {
storageDirectory: string = '';
constructor(public navCtrl: NavController, public navParams: NavParams,
private transfer: FileTransfer, private file: File) {
this.vCardDownload("b734cdc8-8ec1-4fde-b918-b6062b5099df");
}
ionViewDidLoad() {
console.log('ionViewDidLoad QuizPage');
}
vCardDownload(uuid) {
const fileTransfer: TransferObject = this.transfer.create();
const vCardLocation = 'http://xxxxxxx.xxx.edu:5000/get_question_vCard?uuid=' + uuid;
fileTransfer.download(vCardLocation, this.file.applicationDirectory + uuid).then((entry) => {
console.log("file was downloaded", entry.toURL());
alertSuccess.present();
}, (error) => {
console.log("ERROR file was not downloaded");
});
}
}
Where am I going wrong here and how can I achieve file transfer? I think I am on the right track to getting it working -- I am pretty new to typescript and mobile development so I apologize in advance for any mistakes. Essentially I want to "capture the file within the application."
It turns out I had two errors. First, my import statements were wrong. Second, I didn't add certain imports to the providers listing in my app.module.ts file.
Here are my providers in app.module.ts:
import { File } from '#ionic-native/file';
import { FileTransfer } from '#ionic-native/file-transfer';
... declarations, imports, etc. ...
providers: [
StatusBar,
SplashScreen,
File,
FileTransfer,
{provide: ErrorHandler, useClass: IonicErrorHandler}
]
Here is the sample code I used to download the .vcf file.
import { FileTransfer, FileTransferObject } from '#ionic-native/file-transfer';
import { File } from '#ionic-native/file';
...
constructor(public navCtrl: NavController, public navParams: NavParams,
private transfer: FileTransfer, private file: File) {
this.vCardDownload("XXXXXX-XXXXX-XXXX-XXXX");
}
...
vCardDownload(uuid) {
console.log("Trying to download vCard!");
const fileTransfer: FileTransferObject = this.transfer.create();
const vCardLocation = 'http://XXXXXX.XXX.edu:5000/get_question_vCard?uuid=' + uuid;
fileTransfer.download(vCardLocation, this.file.dataDirectory + 'file.vcf').then((entry) => {
console.log('download complete: ' + entry.toURL());
}, (error) => {
console.error(error);
});
}
Note that so far this only works for me on a mobile device.
Followed the content of the url to implement dynamic menu items using JSON file stored under /assets/data. The menu is working fine with stored JSON file. Now I need to dynamically retrieve the JSON of same format in real time from a Salesforce API and display its content.
Can someone please suggest what changes I need to make here? should the json path in getMainMenu() method be replaced with the actual Saleforce API?
Below is the data-service.ts
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
import 'rxjs/add/operator/map';
/*
Generated class for the DataServiceProvider provider.
See https://angular.io/guide/dependency-injection for more info on providers
and Angular DI.
*/
#Injectable()
export class DataServiceProvider {
constructor(public http: Http) {
console.log('Hello DataServiceProvider Provider');
}
getMainMenu(){
return this.http.get('assets/data/mainmenu.json')
.map((response:Response)=>response.json().Categories);
}
}
and 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 { HomePage } from '../pages/home/home';
import { ListPage } from '../pages/list/list';
import { DataServiceProvider } from '../providers/data-service/data-service'
#Component({
templateUrl: 'app.html'
})
export class MyApp {
#ViewChild(Nav) nav: Nav;
rootPage: any = HomePage;
pages: any[]; //Array<{title: string, component: any}>;
mainmenu: any[];
constructor(public platform: Platform, public statusBar: StatusBar, public splashScreen: SplashScreen, public dataService: DataServiceProvider) {
this.initializeApp();
this.dataService.getMainMenu().subscribe((Response)=>{
this.mainmenu = Response;
console.log(this.mainmenu);
});
// used for an example of ngFor and navigation
this.pages = [
{ title: 'Home', component: HomePage },
{ title: 'List', component: ListPage }
];
}
initializeApp() {
this.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.
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
openPage(page) {
// Reset the content nav to have just this page
// we wouldn't want the back button to show in this scenario
this.nav.setRoot(page.component);
}
toggleSection(i) {
this.mainmenu[i].open = !this.mainmenu[i].open;
};
toggleItem(i,j) {
this.mainmenu[i].SubCategories[j].open = !this.mainmenu[i].SubCategories[j].open;
};
}
It looks like you will need to update the url in the getMainMenu method to that of your api. There might be some other changes you will need to make, such as adding authentication headers, but if the data coming from the api is the same as whats stored in the assets folder, your component shouldn't care "where" the data comes from.
What I am trying to do is when the splash screen is loading, a http request is made to the server to pull some information and pass the response to another page.
Below is the code I am working with.
import { Component } from '#angular/core';
import { Platform, LoadingController } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { CacheService } from "ionic-cache/ionic-cache";
import { Apis } from './apis';
import { StayPage} from '../pages/stay/stay';
#Component({
templateUrl: 'app.html',
providers: [Apis]
})
export class MyApp {
rootPage = StayPage;
constructor(platform: Platform, cache: CacheService, public loadingCtrl: LoadingController, public Apis: Apis ) {
cache.setDefaultTTL(60 * 60);
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.
this.Apis.types().subscribe( response => {
response.results;
StatusBar.styleDefault();
Splashscreen.hide();
}, err => {
this.Apis.error( err );
});
});
}
}
When I run the above code, the splash screen is stuck on loading and doesn't move to another page.
You need to make HTTP request in constructor or ngOnInit of StayPage.
export class StayPage implements OnInit {
...
constructor(public navCtrl: NavController,
public navParams: NavParams
public http: Http) { }
ngOnInit(){
this.http.get(apiUrl)
.subscribe(
responseSuccess => ...
responseError => ...
}
}
}