I have been getting an error from the service call when browse is in offline mode. How can check off-line mode and want to block my service call when the browser is the offline mode?
I suggest you to use Offline.js
they have templates and other stuff to work with .
you can check out their documentation and see how it works .
it gets you the current state of the connection by returning the "up" or "down" result , or you can bind and event to it and use it across you'r application .
this is what they say about their library :
Offline.js is a library to automatically alert your users when they've lost internet connectivity, like Gmail.
It captures AJAX requests which were made while the connection was down, and remakes them when it's back up, so your app reacts perfectly.
It has a number of beautiful themes and requires no configuration.
good luck and have fun.
Check for navigator.onLineand based on this value decide whether to send request or not.
if (navigator.onLine) {
$http.get('url').success(function() {});
}
else {
// no req
}
Angular way:
Use $q service - A service that helps you run functions asynchronously, and use their return values (or exceptions) when they are done processing. https://docs.angularjs.org/api/ng/service/$q
The best way that I would know would be to intercept the HTTP handler, if its a 401 / 501/ etc. then to handle it according
angular.module('myApp', ['myApp.services'],
function ($httpProvider) {
var interceptor = ['$rootScope', '$q', function ($rootScope, $q) {
function success(response) {
return response;
}
function error(response) {
var status = response.status; // error code
if ((status >= 400) && (status < 500)) {
$rootScope.broadcast("AuthError", status);
return;
}
if ( (status >= 500) && (status < 600) ) {
$rootScope.broadcast("ServerError", status);
return;
}
// otherwise
return $q.reject(response);
}
return function (promise) {
return promise.then(success, error);
}
}];
$httpProvider.responseInterceptors.push(interceptor);
then in your code that listens for the on of, just add in
$rootScope.$on("ServerError", someServerErrorFunction);
Source: How to detect when online/offline status changes
Online/offline detection cannot be 100% accurately decided because network status can vary for a number of reasons.
Still, if you want an implementation of the same with Angular+NGRX, You can find more details here.
https://hackernoon.com/using-angular-to-detect-network-connection-status-onlineoffline
import { Component, OnDestroy, OnInit, VERSION } from '#angular/core';
import { fromEvent, merge, of, Subscription } from 'rxjs';
import { map } from 'rxjs/operators';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
networkStatus: boolean = false;
networkStatus$: Subscription = Subscription.EMPTY;
constructor() {}
ngOnInit(): void {
this.checkNetworkStatus();
}
ngOnDestroy(): void {
this.networkStatus$.unsubscribe();
}
checkNetworkStatus() {
this.networkStatus = navigator.onLine;
this.networkStatus$ = merge(
of(null),
fromEvent(window, 'online'),
fromEvent(window, 'offline')
)
.pipe(map(() => navigator.onLine))
.subscribe(status => {
console.log('status', status);
this.networkStatus = status;
});
}
}
You can see the demo here.
or check the code here
Happy coding!!! 🎉🎉🎉
Related
http request is not executed
#HostListener('window:beforeunload')
async ngOnDestroy() {
await this.microSitioService.cancelarTransaccion(this.tarjetaCreditoService.seguimientoEtapa).then(() => {});
}
I need to execute an http request when the on destroy is executed
EDIT: Revised Answer
Ok, this is the format for when you want to make certain onDestroy is called - and also stop navigation away, using $event and preventDefault. I've also added how you can return a message to the browser to describe why nav was halted. You can use this to ensure that the http request is working as intended.
#HostListener('window:beforeunload', ['$event'])
async ngOnDestroy($event) {
if (this.componentSub) {
// handle unsubscriptions
this.componentSub.unsubscribe();
}
await this.microSitioService
.cancelarTransaccion(this.tarjetaCreditoService.seguimientoEtapa)
.then(() => {});
$event.preventDefault();
$event.returnValue = 'A message.';
}
Side Note: Have you included onDestroy as an implements on the class definition?
import { Component, OnDestroy, HostListener } from '#angular/core';
class MyComponent implements onDestroy {
If you are looking for an event that executes when the angular app is destroyed, you can use the PlatformRef which has an OnDestroy() callback
in main.ts
function doSomethingOnAppDestory() {
console.log('test');
}
platformBrowserDynamic().bootstrapModule(AppModule).then(ref => {
// Ensure Angular destroys itself on hot reloads.
if (window['ngRef']) {
window['ngRef'].destroy();
}
window['ngRef'] = ref;
ref.onDestroy(doSomethingOnAppDestory);
// Otherwise, log the boot error
}).catch(err => console.error(err));
See the stackblitz demo
I am developing a page that shows real-time data from a server. Now i'm testing it with some mqtt client websocket (like hivemq). The value itself that i receive is showed in the chrome console,but i'm trying to make this value graphical with NGX-GAUGE.
The ngx-gauge is showed correctly in the page,and if i put in "gaugeValue" a standard number it works (also with a Math.Random), but if i take a value from a MQTT broker,it just doesn't do anything
when i try to get the value from an MQTT broker, the value and green line of the ngx-gauge (which should increase/decrease in real time) doesn't do anything
import { Component, OnInit } from '#angular/core';
import { Paho } from 'ng2-mqtt/mqttws31';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
valore:String;
gaugeType = "semi";
gaugeValue=this.valore;
gaugeLabel = "Valore";
gaugeAppendText = "km/hr";s
animate=true;
duration=1500;
private client;
mqttbroker = 'broker.mqttdashboard.com';
ngOnInit() {
this.client = new Paho.MQTT.Client(this.mqttbroker, Number(8000), 'client1');
this.client.onMessageArrived=this.onMessageArrived.bind(this);
this.client.onConnectionLost=this.onConnectionLost.bind(this);
this.client.connect({onSuccess: this.onConnect.bind(this)});
}
onConnect() {
console.log('onConnect');
this.client.subscribe('testtopic/40/xxx');
}
onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log('onConnectionLost:' + responseObject.errorMessage);
}
}
onMessageArrived(message) {
console.log('onMessageArrived: ' + message.destinationName + ': ' + message.payloadString);
if (message.destinationName.indexOf('xxx') !== -1) {
this.valore = (message.payloadString);
}
}
}
It should simply show the value,with the line respondig in real time with that value
I also faced the same issue but I solved it after writing code by this way :
gaugeValue= 0; //define minimum value in export
this.gaugeValue= (message.payloadString); // intead of "this.valore" use this.gaugeValue
Please refer screenshot 1 & 2 for more understandings;
I used _thoughput_gaugeValue for defining
same _thoughput_gaugeValue is used as this._thoughput_gaugeValue for getting data. Do not declare _thoughput_gaugeValue:any
I have the Tour of Heroes app running, but I want to extend it to make ajax calls.
I have a WebAPI service that serves up the data (CORS enabled) and have proven it w/ a silly little non Angular client using JQuery $.post and $GetJson ... All was going well...
Here is my hero-details.component.ts file
(happy to include any others that may help...)
import {Component , Input, OnInit } from '#angular/core';
import { ActivatedRoute, Params } from '#angular/router';
import { Location } from '#angular/common';
import { HttpModule } from '#angular/http';
import 'rxjs/add/operator/switchMap';
import { Hero } from './hero';
import { HeroService } from './hero.service';
#Component({
selector: 'hero-detail',
templateUrl: './hero-detail.component.html',
styleUrls : ['./hero-detail.component.css']
})
export class HeroDetailComponent { // implements OnInit {
#Input() hero: Hero;
powers = ['Really Smart', 'Super Flexible', 'Weather Changer'];
submitted = false;
constructor(
private heroService: HeroService,
private route: ActivatedRoute,
private location: Location,
$http //**--LINE OF INTEREST #2**
) { }
ngOnInit(): void {
this.route.params
.switchMap((params: Params) => this.heroService.getHero(+params['id']))
}
save(): void {
this.heroService.update(this.hero)
.then(() => this.goBack());
}
goBack(): void {
this.location.back();
}
onSubmit() { this.submitted = true; }
callService( ) {
var uri = 'http://localhost:61212/api/heros';
//**// LINE OF INTEREST #1**
$http({
method: 'GET',
url: uri
}).then(function () { alert('success'); }, function () { alert('fail');});
};
}
If I try to compile I get
TS2304: Cannot find '$http'
I can comment the $HTTP call (Line of Interest #1 ) and it compiles, it runs and i do enter the function and hit a breakpoint where i declare and assign the variable "uri". So I am reasonably sure I have the problem isolated.
So I believe, based on hours of googling, that I need to DI the $http object into this component
But when I pass $http into the constructor (LINE OF INTEREST #2) I get the following error when I try to compile
TS7006 Parameter '$http' implicitly has an 'any' type
I have googled this so much Larry and Sergy have asked me to knock it off.
What I have found is $http being passed into controllers, maybe Im missing something, but I can not seem to translate those articles into something that works for this.
1) Am I right that injecting the $http object is what needs to be done
2) What is the syntax?
when I was googling , i was just googling angular and most the articles were for angular1. Thats why I was seeing answers that involved controllers, etc.
angular2 is much different. If you are trying to get off the ground, try searching angular2 instead. at least the articles you run across will be relevant.
if you are using visual studio.. here is a nice link to get you started...
https://jonhilton.net/2016/12/01/fast-track-your-angular-2-and-net-core-web-app-development/
I try to query an api which is not the same origin with the aurelia-http-client.
My code pretty simple :
import {HttpClient} from 'aurelia-http-client';
export class App {
constructor(){
console.log("constructor called");
let url = 'http://localhost:8081/all';
let client = new HttpClient();
client
.jsonp(url)
.then(data => {
console.log("datas");
console.log(data);
});
}
}
Nothing happens, I can see in network that the url is called, my api engine logs an entry but I never enter in the "then" of the "promise"...
What's wrong ?
Update :
I give you some screenshots with catch
code source
browser result
With JQuery on the same machine no problems.
After reading this post other jsonp case I try to add the work "callback" and now it works !!!
so call jsonp(url, 'callback')
client.jsonp(url, 'callback')
Thanks...
This may not be a direct answer but just a suggestion, I would rather use the aurelia API as I found it more consistent and stable.
just add it as plugin in you main :
.plugin('aurelia-api', config => {
config.registerEndpoint('github', 'https://api.github.com/');
});
and use it as:
import {Endpoint} from 'aurelia-api':
#autoinject
export class Users{
constructor(private githubEndpoint){
}
activate() {
return this.githubEndpoint.find('users')
.then(users => this.users = users);
}
}
Source: https://aurelia-api.spoonx.org/Quick%20start.html
How can I make basic initialization of my data in app. For example if user logged in and press F5 I need to request current user data from server before all queries starts like get user order etc. In Angular 1 we have .run() directive for this case. How can I solve this problem?
There are several ways to do that:
You could execute some requests before bootstrapping your Angular2 application. Such first requests could rely what you save into the local / session storage.
var injector = Injector.resolveAndCreate([HTTP_PROVIDERS]);
var http = injector.get(Http);
http.get('/userdetails').map(res => res.json())
.subscribe(data => {
bootstrap(AppComponent, [
HTTP_PROVIDERS
provide('userDetails', { useValue: data })
]);
});
See this question for more details:
How to bootstrap an Angular 2 application asynchronously
You could extend the HTTP request to transparently get these data when requests are actually executed. This would be a lazy approach.
#Injectable()
export class CustomHttp extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, userDetailsService: UserDetailsService) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
console.log('request...');
return this.userDetailsService.getUserDetails().flatMap((userDetails) => {
return super.request(url, options);
});
}
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
console.log('get...');
return this.userDetailsService.getUserDetails().flatMap((userDetails) => {
return super.get(url, options);
});
}
}
implement the UserDetailsDetails this way:
export class UserDetailsService {
constructor(private http:Http) {
}
getUserDetails() {
if (this.userDetails) {
return Observable.of(this.userDetails);
} else {
return this.http.get(...)
.map(...)
.do(data => {
this.userDetails = data;
// Store in local storage or session storage
});
}
}
and register this CustomHttp class this way:
bootstrap(AppComponent, [HTTP_PROVIDERS,
UserDetailsService,
new Provider(Http, {
useFactory: (backend: XHRBackend,
defaultOptions: RequestOptions,
userDetailsService: UserDetailsService) => new CustomHttp(backend, defaultOptions, userDetailsService),
deps: [XHRBackend, RequestOptions, UserDetailsService]
})
]);
See these questions for more details:
Angular 2 - How to get Observable.throw globally
Cache custom component content in ionic 2
Things could also be done at the level of the router outlet if you use routing. It's possible to implement a custom router-outlet that checks security / user details when a route is activated. I think that it's a little further from your need...
See this question for more details:
Angular 2 Cancelling Route Navigation on UnAuthenticate
You could fetch the current user data before you call Angular2's bootstrap(...)
You could also fire an event (using an Observable for example) to notify other that the logged-in user is now known and initiate further requests only after this event was received.