Network service not working in browser - ionic-framework

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

Related

AngularFire2: you are using the development build of the firebase SDK

So i'm using the official documentation to setup and install angularfire2.
https://github.com/angular/angularfire2/blob/master/docs/install-and-setup.md
This works fine, my data is coming in but when building for production i get this error:
It looks like you're using the development build of the Firebase JS
SDK. When deploying Firebase apps to production, it is advisable to
only import the individual SDK components you intend to use.
For the CDN builds, these are available in the following manner
(replace with the name of a component - i.e. auth, database,
etc):
I tried every suggestion out there but nothing is working.
Any Ideas?
thx,
Root module
import { NgModule } from '#angular/core';
import { RouterModule } from '#angular/router';
import { NoopAnimationsModule } from '#angular/platform-browser/animations';
import { RootComponent } from './rootComponent.component';
import { ROOT_ROUTES } from './root.routes';
import { BrowserModule, Title } from '#angular/platform-browser';
import { AngularFireModule } from '#angular/fire';
import { AngularFirestoreModule } from '#angular/fire/firestore';
import { environment } from '../environments/environment';
#NgModule({
declarations: [RootComponent],
imports: [
AngularFireModule.initializeApp(environment.firebase),
AngularFirestoreModule,
NoopAnimationsModule,
BrowserModule,
RouterModule.forRoot(ROOT_ROUTES)
],
providers: [Title],
bootstrap: [RootComponent]
})
export class RootModule {}
Component
import { Component, OnInit } from '#angular/core';
import { MatTableDataSource } from '#angular/material';
import { AngularFirestore } from '#angular/fire/firestore';
import { Observable } from 'rxjs';
import { ActivatedRoute } from '#angular/router';
import { Seal } from '../seals.types';
import { StudioService } from '../../../service/studio.service';
#Component({
selector: 'seals-component',
templateUrl: './seals.component.html'
})
export class SealsComponent implements OnInit {
constructor(private db:AngularFirestore, private studioService: StudioService) {
this.getData();
}
items: Observable<any[]>;
dataSource = new MatTableDataSource<Seal[]>();;
displayedColumns: string[] = ['description', 'language', 'seal', 'type'];
pID:string = 'flsjezlijlsfj';
ngOnInit() {}
getData() {
this.items = this.db.collection(`sealsDB/TNDorQMQOzoqY6P6Ej0i/seal/${this.pID}/seal/`).valueChanges();
this.items.subscribe(seals => {
this.dataSource.data = seals
})
}
}
I was having the same warning and it took me a while to figure it out that I was using the User interface from firebase/auth, along with Timestamp.fromDate() in other file.
So I added:
import * as firebase from 'firebase/app';
import { User } from 'firebase/auth';
and just
import * as firebase from 'firebase/app';
where I used
firebase.firestore.Timestamp.fromDate()
This got rid of the warning.

Ionic ngx-translate giving me assets/i18n/.json 404 (Not Found)

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/");

how to get realtime JSON from endpoint in Ionic App

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.

Splash screen make http request and pass the response to another page

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 => ...
}
}
}

How to subscribe Ionic 2 platform.pause EventEmitter?

I'm trying to use the following code to subscribe, but it doesn't work.
import { Platform } from 'ionic-angular';
#Page({
templateUrl: 'build/pages/test.html',
})
export class Test {
constructor(private platform: Platform) {
this.platform.pause.subscribe(() => {
console.log('paused')
});
}
}
I'm using Ionic 2 with TypeScript, Angular 2. As platform.pause is an EventEmitter provided by Ionic 2, I suppose it should be able to be subscribed. However, when I put the application to the background, console.log('pause') is not fired.
Should I add Platform to providers or something like that? Plus, this.platform is not null. this.platform.ready().then(()=>{console.log('ready')}) works perfectly.
I think you missed platform.ready() as below
constructor( private platform: Platform ) {
platform.ready().then(() => {
this.platform.pause.subscribe(() => {
console.log('[INFO] App paused');
});
this.platform.resume.subscribe(() => {
console.log('[INFO] App resumed');
});
});
}
The above code worked for me. Hope it helps you as well.