How to see the state of the battery with Ionic4? - ionic-framework

I can not get the battery data, the level of charge and whether it is connected or not, what am I doing wrong? Thank you in advance.
I'm placing "BatteryStatus" in app.module.ts in providers. The code of the home is only for printing on the console while there is a change in the battery. I am using the example of the Ionic 4 documentation but still I have the following error: ERROR TypeError: Invalid event target.
I HAVE FOLLOWED THE SENTENCES OF THE DOCUMENTATION
The code of the home is the following:
import { Component } from '#angular/core';
import { BatteryStatus } from '#ionic-native/battery-status/ngx';
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
subscription: any;
constructor(private batteryStatus: BatteryStatus) {
this.checkStatus()
}
checkStatus(){
this.subscription = this.batteryStatus.onChange().subscribe(status => {
console.log(status.level, status.isPlugged);
});
}
stop(){
// stop watch
this.subscription.unsubscribe();
}
}
I hope that the status value of the battery is printed in the console, but I get the following error:
Error

Related

Capacitor v3 Motion api - using AccelListenerEvent properties

I am using Capacitor version 3 and I'm trying out the Motion Api.
In the documentation here, the AccelListenerEvent comes with some properties which I want to set but there are no examples of how to use this.
So the part I'm using is addListener(‘orientation’, …)
I basically want to set the interval.
I've added this:
import { Component } from '#angular/core';
import { PluginListenerHandle } from '#capacitor/core';
import { Motion, AccelListenerEvent } from '#capacitor/motion';
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
accelHandler: PluginListenerHandle;
accelListenerEvent: AccelListenerEvent;
constructor() {
this.accelListenerEvent.interval = 10;
}
But it doesn't like it in the constructor.
Does anyone have any ideas on how to set these properties?
You can access the properties this way:
Motion.addListener('accel', event => {
console.log('Interval:', event.interval);
});
Since this is an event, you can only receive values, not set them.

How do you setup angular-bootstrap-toggle on an Angular 9 app?

I'm learning Angular 9 and have gone through the Tour of Heroes app and tutorial. I've used this tutorial as a base to add new features such as CRUD operations on a remote resource and I have added #ng-bootstrap/ng-bootstrap to the projects but I cannot get angular-bootstrap-toggle to work.
The instructions on Bootstrap Toggle don't match what I have learned so far and I can't find a solution anywhere.
For example, I don't know how this command angular.module('myApp', ['ui.toggle']); fits in with Angular 9 and the tutorial I have used.
How can I get the system to call onChange() when I click the toggle?
angular.json
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"node_modules/bootstrap4-toggle/css/bootstrap4-toggle.min.css",
"src/styles.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/bootstrap/dist/js/bootstrap.bundle.js",
"node_modules/bootstrap4-toggle/js/bootstrap4-toggle.min.js"
]
navigation-bar.component.html This displays correctly and toggles as expected
<input id="local-browse" (change)="onChange()" type="checkbox" checked="" data-toggle="toggle" data-on="Local" data-off="Remote" data-onstyle="success" data-offstyle="danger" data-size="sm">
navigation-bar.component.ts If I put in a standard checkbox the onChange() does work as expected but not with angular-bootstrap-toggle
import { Component, OnInit } from '#angular/core';
declare var $: any;
#Component({
selector: 'app-navigation-bar',
templateUrl: './navigation-bar.component.html',
styleUrls: ['./navigation-bar.component.css'],
})
export class NavigationBarComponent implements OnInit {
localUrl = 'http://192.168.253.53';
remoteUrl = 'https://remoteaddress.com';
local = true;
constructor() {}
ngOnInit(): void {
$(document).ready(() => {
console.log('The document ready for jQuery!');
});
}
onChange() {
if (this.local === true) {
this.local = false;
} else {
this.local = true;
}
}
}
I dont think it is compatible with Angular 2+ (or at least angular 9).
You may like to use ng-toggle from https://www.npmjs.com/package/#nth-cloud/ng-toggle
Which is tested on Angular 9.
More information about installation in https://nth-cloud.github.io/ng-toggle/#/home

How to hide header on scroll in ionic 4?

I wanted to know how I can hide a header in Ionic 4 by scrolling down the page, and re-show it when scrolling up.
I found many solutions on how to do that, but they all turned out to not working or being out-of-date.
So I collected all piece of information I could find to provide this answer.
Thanks to this video I got it to work.
First of all call ionic g directive directives/hide-header. You can of course replace directive/hide-header with your own path and name.
hide-header.directive.ts
import { Directive, HostListener, Input, OnInit, Renderer2 } from '#angular/core';
import { DomController } from '#ionic/angular';
#Directive({
selector: '[appHideHeader]'
})
export class HideHeaderDirective implements OnInit {
#Input('header') header: any;
private lastY = 0;
constructor(
private renderer: Renderer2,
private domCtrl: DomController
) { }
ngOnInit(): void {
this.header = this.header.el;
this.domCtrl.write(() => {
this.renderer.setStyle(this.header, 'transition', 'margin-top 700ms');
});
}
#HostListener('ionScroll', ['$event']) onContentScroll($event: any) {
if ($event.detail.scrollTop > this.lastY) {
this.domCtrl.write(() => {
this.renderer.setStyle(this.header, 'margin-top', `-${ this.header.clientHeight }px`);
});
} else {
this.domCtrl.write(() => {
this.renderer.setStyle(this.header, 'margin-top', '0');
});
}
this.lastY = $event.detail.scrollTop;
}
}
After that, in your template:
<ion-header #header>
<ion-toolbar><ion-title>Test</ion-title></ion-toolbar>
</ion-header>
<ion-content scrollEvents="true" appHideHeader [header]="header">
</ion-content>
Take care of the scrollEvents, appHideHeader and the [header] attributes! The last one takes the header element as argument, in this case #header.
Most of the code is the same as shown in the video. I changed the host-property from the #Directive and used the more up-to-date HostListener.
If you want to use the directive in more than one directive, you need to create a SharedModule.
To do so, create the module with ng g module shared. After that, add the HideHeaderDirective to the declarations and the exports array.
shared.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { HideHeaderDirective } from './directives/hide-header.directive';
#NgModule({
declarations: [HideHeaderDirective],
exports: [HideHeaderDirective],
imports: [
CommonModule
]
})
export class SharedModule {}
Now add the shared module to all the modules you want to use the directive in.
Note: You cannot import the directive in app.module.ts and use it in a submodule! You have to import the shared module in every direct module you want to use the directive in.
My current versions of node, npm and ionic:
For this you can just place the ion-header before the ion-content. this is the simple answer for that.

angular2 submit form in typescript

I need to submit a form coming from a payment gateway. Our backend guy asks me to either put the innerHtml and send after it rendered. I got it to work on Chrome, but failed on Firefox.
Now I'm trying to fix it on our testing environment, the backend added a JSON return of all the properties I need to replicate the form he was sending me so I can make my own form. But still failing to submit on Firefox.
Does someone have the same experience? Please shed me some light.
Is there any Firefox specific fixes I need to know?
Below is the working code on Chrome and Safari
import { Component, OnInit, AfterViewInit, ViewChild, ElementRef,DoCheck, ViewChildren, QueryList } from '#angular/core';
import { BrowserModule, DomSanitizer, SafeResourceUrl, SafeUrl} from '#angular/platform-browser';
import { PaymentService } from '../../_services/payment.service';
import { Loader } from '../../_services/loader.service';
#Component({
selector: 'bdf-payment-form',
templateUrl: './payment-form.component.html',
styleUrls: ['./payment-form.component.scss']
})
export class PaymentFormComponent implements OnInit,DoCheck, AfterViewInit {
form : SafeResourceUrl;
// #ViewChild('paymentFormContainer') container: ElementRef;
#ViewChild('paymentForm') myForm: ElementRef;
loader;
constructor(private paymentService:PaymentService,
private sanitizer: DomSanitizer,
private loaderService: Loader,
private elRef:ElementRef) { }
ngDoCheck(){
}
ngOnInit() {
console.log(this.paymentService.paymentForm);
this.paymentService.paymentForm ? this.form = this.sanitizer.bypassSecurityTrustHtml(this.paymentService.paymentForm) : null
this.loader = true;
}
ngAfterViewInit() {
let test;
if(this.form){
test = this.elRef.nativeElement.querySelector('form')
console.log(test)
test.submit();
}
}
}
You shouldn't use submit() method to avoid redirection with page refresh.
The http service is used to submit the form data serialized to json from the form. If you have form elements bound to the model then it would be easier to send the model back to the backend.

Angular2 Undefined Object attribute when using a callback function as Component #Input()

Im trying to bind a callback function to a directive, when the event is fired the attribute of the parent component are undefined
app.ts
import {Component} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {MyComponent} from './my-component';
#Component({
selector: 'my-app',
template: `
<button (click)="appOnClick('CLICK FROM APP')">BUTTOM OUTSIDE COMPONENT</button>
<br><br>
<my-component [onClick]="appOnClick"></my-component>`,
directives: [MyComponent]
})
export class MyApp {
public theBoundCallback: Function;
test:string = "THIS SHOULD HAVE A VALUE";
public ngOnInit(){
this.theBoundCallback = this.appOnClick.bind(this);
}
appOnClick(someText){
console.log(someText);
console.log(this.test);
}
}
bootstrap(MyApp);
my-component.ts
import {Component, Input} from 'angular2/core';
#Component({
selector: 'my-component',
template: `<button (click)="onClick('CLICK FROM COMPONENT')">BUTTOM INSIDE COMPONENT</button>`
})
export class MyComponent{
#Input() onClick: Function;
}
That will render two buttons:
BUTTOM OUTSIDE COMPONENT, this calls the appOnClick function direct from the app, when clicked the console shows:
- CLICK FROM APP
- THIS SHOULD HAVE A VALUE
BUTTOM INSIDE COMPONENT, this calls the appOnClick function via the #Input function in the component, when clicked the console shows:
- CLICK FROM APP
- undefined
I've created the example on Plunker
Is that a way to assign this correctly so I can work with my object attributes when the callback is trigger?
Updated plunkr
In order to pass appOnClick around this way, you need to declare it as a property like so:
export class MyApp {
...
appOnClick = (someText) => {
console.log(someText);
console.log(this.test);
}
}
instead of:
export class MyApp {
...
appOnClick(someText){
console.log(someText);
console.log(this.test);
}
}
I think that you forgot "(...)" when using the appOnClick method and use "[...]" instead of "(...)" when configuring the event handler:
<my-component (onClick)="appOnClick($event)"></my-component>`,
Moreover within your sub component you need to define a custom event with "#Output":
#Component({
selector: 'my-component',
template: `<button (click)="handleClick('CLICK FROM COMPONENT')">BUTTOM INSIDE COMPONENT</button>`
})
export class MyComponent{
#Output()
onClick:EventEmitter<string> = new EventEmitter();
handleClick(txt:string) {
this.onClick.emit(txt);
}
}