DOM manipulation is slow in angular while using jquery - javascript

I was developing an Angular app, in my dashboard.comp.ts I need to implement jquery event (due to other reason I have used jquery), jquery event working properly with my typescript objects. Now problem is when I click through jquery, DOM manipulation getting delay, so that, output getting delay like: 5/7 seconds.
dashboard.comp.ts
import { Component, OnInit} from '#angular/core';
import SensorServices from '../Services/Settings/SensorServices';
declare var $: any;
#Component({
selector: 'app-root',
templateUrl: '../Views/Dashboard.html',
providers: [SensorServices]
})
export class DashboardComponent implements OnInit {
public sensor: any;
constructor(private _sensorServices: SensorServices )
{
}
ngOnInit(): void {
this._sensorServices.getAll({})
.subscribe((result) => {
var self=this;
$(document).on('click', '.sensorSizeInDesign', function (e) {
self.sensor=result;
});
});
}
}
html
N.B: the given html is fewer basically element generated from server side, so there are multiple sensors. here is an example.
<div class='sensorSizeInDesign' data-sensorId="123"></div>
<h3>{{sensor.Port}}</h3>
For each click event Port getting delay to be changed.

avoid using jQuery inside angular applications. Therefor #ViewChild exists:
https://angular.io/api/core/ViewChild
Your click handler should be implemented this way:
function onClick() {
this._sensorServices.getAll({}).subscribe((result) => {
this.sensor=result;
})
}
HTML:
<div class='sensorSizeInDesign' (click)="onClick()" data-sensorId="123"></div>
<h3>{{sensor.Port}}</h3>

ngOnInit(): void {
this._sensorServices.getAll({})
.subscribe((result) => {
var self=this;
$( window ).on( "load", function(){
$(document).on('click', '.sensorSizeInDesign', function (e) {
self.sensor=result;
});
});
});
Try that

Finally i got the solution: just updating my jquery code:
ngOnInit(): void {
this._sensorServices.getAll({})
.subscribe((result) => {
var self=this;
$('.sensorSizeInDesign').click(function(e){
self.sensor=result;
})
});
}

Related

Detect when a programmatically opened tab is closed by the user

I'm making a webapp with Angular 11 that uses the msgraph API to upload files to onedrive/sharepoint and then open the file in the Office online editor. This part is simple enough. I Also need to get the file back when the user is done with it. The requirement is that when the user closes the editor-tab I need to be notified of it, so I can download the file and delete it from onedrive/sharepoint.
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-test-page',
templateUrl: './test-page.component.html',
styleUrls: ['./test-page.component.scss']
})
export class TestPageComponent implements OnInit {
constructor() { }
winGoogle!: Window | null;
interval!: NodeJS.Timeout;
ngOnInit(): void {
this.interval = setInterval(this.detectClose, 1000);
}
openWin () {
this.winGoogle = window.open('http://google.com', '_blank');
}
closeWin () {
if(this.winGoogle) {
this.winGoogle.close();
}
}
detectClose() {
//detect if the tab is closed by the user ( not from code ) and remove the interval
clearInterval(this.interval)
}
}
I tried to look at the value of the "handler" (this.winGoogle), but its undefined at all times.
Does anyone know how can I achieve it or is it at all possible?
Seems like it can't be done without writing a browser extension.

Call http request on destroy angular

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

Calling custom jQuery function inside Angular Component class

I have one custom query function written in a javascript file under the source folder (i.e. /src/assets/inlineedit.js) of Angular application.
Here's the content of the file.
$.fn.inlineEdit = function(replaceWith, connectWith) {
$(this).hover(function() {
$(this).addClass('hover');
}, function() {
$(this).removeClass('hover');
});
$(this).click(function() {
var elem = $(this);
elem.hide();
elem.after(replaceWith);
replaceWith.focus();
replaceWith.blur(function() {
if ($(this).val() != "") {
connectWith.val($(this).val()).change();
elem.text($(this).val());
}
$(this).remove();
elem.show();
});
});
};
Now, I want to call this function within Angular mycomponent.ts file and content looks as below:
import { Component, ViewChild, ElementRef } from '#angular/core';
#Component({
selector: 'app-pivotgrid',
templateUrl: './mycomponent.component.html',
styleUrls: ['./mycomponent.component.css']
})
export class mycomponent {
OnCellclick (event): void
{
var replaceWith = $('<input name="temp" type="text" />'),
connectWith = $('input[name="hiddenField"]');
$('#innerDiv').inlineEdit(replaceWith, connectWith);
}
}
But, I'm getting error like
Property 'inlineEdit' does not exist on type 'JQuery'
How to call jQuery functions inside Angular components?
You could use <any> type-casting like this:
(<any>$('#innerDiv')).inlineEdit(replaceWith, connectWith);
Or even better:
First install #types/jquery from npm
npm install #types/jquery --save-dev
Then add a local typings file and declare your plugin function in it
interface JQuery {
<your-plugin-name>(options?: any): any;
}
Then you can use your plugin.
Source: https://medium.com/all-is-web/angular-5-using-jquery-plugins-5edf4e642969

How do I access angular component function from a global function - IE11 compatible please

Here is the situation - I'm working with the Mastercard payment gateway api in an angular based application. The api takes a callback for success and error and the callback is passed in the data-error and data-success attributes of the script tag to load the Mastercard api.
<script src="https://eu-gateway.mastercard.com/checkout/version/49/checkout.js"
data-error="errorCallback"
data-cancel="cancelCallback">
</script>
Details here.
I have a solution which works quite well in Firefox and Chrome but absolutely fails in IE11. I've uncommented all the polyfills imports but nothing is working no matter how much I try.
Here is what I have done so far:
export class AppComponent implements OnInit {
constructor(private ngZone: NgZone, private router:Router) {
var _self = this;
(<any>window).errorPaymentCallback = function(error){
console.log(error);
};
(<any>window).cancelPaymentCallback = function(){
console.log('cancel');
};
}
No matter what I try the callbacks are not fired and instead the api returns an error. Any ideas?
You can dispatch an event and then catch it in AppComponent
This is how you do this:
<script src="https://eu-gateway.mastercard.com/checkout/version/49/checkout.js"
data-error="errorCallback"
data-cancel="cancelCallback">
</script>
<script type="text/javascript">
function errorCallback(error) { document.dispatchEvent(new Event('payment-error', { bubbles: true })); }
function cancelCallback() { document.dispatchEvent(new Event('payment-error', { bubbles: true })); }
window.global = window;
</script>
In AppComponent
#HostListener('document:payment-error', ['$event'])
paymentError(event){
//do your work
}

On calling JavaScript file from Angular 2 project

I had written a calendar control in jQuery that I wanted to use in an Angular 2 project.
I've learned from other answers on this topic that I can use jQuery's getScript() API to call into external JavaScript files.
My calendar.component.ts looks like this:
import { Component, OnInit, AfterViewInit } from '#angular/core';
import { Auth } from '../auth.service';
declare var $:any;
declare var CustomCal:any;
#Component({
selector: 'app-calendar',
templateUrl: './calendar.component.html',
styleUrls: ['./calendar.component.css']
})
export class CalendarComponent implements OnInit {
private year : number;
myCal : any;
constructor(private auth : Auth) {
}
ngOnInit() {
}
ngAfterViewInit() {
this.year = 2017;
$.getScript('./app/calendar/zapCalendar.js', function(){
console.log("got call'd back");
this.myCal = new CustomCal(2017);
});
}
}
I get the console message "got call'd back", then an error message stating that CustomCal is not defined.
My CustomCal class is defined in zapCalendar.js as follows:
class CustomCal
{
constructor(nYear) {
this._mouseDown = false;
this._mouseDrag = false;
this._lastItem = 0;
this._nYear = nYear;
this.CreateCalendarFrame();
this.AddEventHandlers(this);
}
...
}
I've tried export'ing the class in the zapCalendar.js file, and also tried adding the following to the zapCalendar.js file:
$( function() {
var myCal = new CustomCal(2017);
});
What am I missing here?
Update:
I've just replaced this (in zapCalendar.js)
$( function() {
var myCal = new CustomCal(2017);
});
with this:
var x = new CustomCal(2017);
And now the calendar is rendering correctly. But I'd like (if possible) to get a reference to the calendar in my typescript. Is this possible?
$.getScript('./app/calendar/zapCalendar.js', function(){
console.log("got call'd back");
this.myCal = new CustomCal(2017);
});
The inner function here will not have the same this reference because it won't be called bound to your object. Since you're using TypeScript, you can just use an arrow function to change this behavior.
$.getScript('./app/calendar/zapCalendar.js', () => {
console.log("got call'd back");
this.myCal = new CustomCal(2017);
});
you need to export class then import it in your component
import {CustomCal} from "./app/calendar/zapCalendar";

Categories

Resources