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";
Related
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
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 am trying to understand Meteor.publish() and Meteor.subscribe(), with help from this video.
I have a collection defined like this:
export const Chansons = new Mongo.Collection('chansons');
Which I publish on my server:
Meteor.publish("chansons", function(){
return Chansons.find();
});
But then when I try to subscribe to it on my client, I have an error:
While building for web.browser:
imports/ui/body.js:17:14: Unexpected token, expected ";" (17:14)
What I do not get is that I wrote the code exactly like in the video, and it worked at first!
constructor() {
super();
this.state = {
subscription: {
chansons: Meteor.subscribe("chansons")
}
}
}
I then changed the formatting of my code somewhere else and now this error appeared and I cannot seem to fix it.
The error seems to come from the constructor(), since it goes away when I delete this block of code.
I know this question is really stupid, but I have no idea how to fix this.
edit: here is the whole body.js:
//Importation des méthodes
import { Template } from 'meteor/templating';
import { Meteor } from 'meteor/meteor';
import { Chansons } from '../api/chansons.js'
//Importation de body
import './body.html';
//Importation des templates
import './templates/header.html';
import './templates/youTube.html';
import './templates/search.html';
import './templates/parametres.html';
import './templates/affichagePlaylist.html';
//Subscription à la collection de chansons
constructor() {
super();
this.state = {
subscription: {
chansons: Meteor.subscribe("chansons")
}
}
}
//Lancement de YouTube
if (Meteor.isClient) {
onYouTubeIframeAPIReady = function() {
player = new YT.Player("player", {
//height: "400",
//width: "600",
videoId: "fkk1vg0nAfc",
events: {
onReady: function (event) {
event.target.playVideo();
}
}
});
};
YT.load();
};
Template.body.helpers({
chansons(){
return Chansons.find({})
}
});
Template.search.events({
'click #Ajouter' : function(){
const vidURL = document.getElementById("URL").value;
Chansons.insert({
URL : vidURL
});
const URLs = Chansons.find({},{ fields: { URL: 1, _id: 0 } }).map((chanson) => chanson.URL);
console.log(URLs);
}
});
Your statement with constructor() {} outside of a class declaration is invalid syntax.
You can declare a function using the short syntax version only within the scope of an object (or a class) in ES6. They are referred to as "methods" (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions)
With Meteor's Blaze frontend, you probably want to subscribe when the template instance is created, i.e.:
Template.body.onCreated(function () {
this.subscribe("chansons"); // Similar to Meteor.subscribe, but scoped to the template instance.
});
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;
})
});
}
Hi, I use a third party library simple-peer which I did declared declare var SimplePeer: any; in angular 4 , than the all logic of that is warped in navigator.n.mediaDevices.getUserMedia() (asking user for video/audio permission) which is asynchronous function and the problem is that SimplePeer returns some data that I need to use in my html but I can't output the data in my html only with console.log() , here is the code app.component.html:
<input type="text" [(ngModel)]="targetpeer">
<button (click)="connect()">Connect</button>
<button (click)="message()">Send Message</button>
<p>{{texttoken}}</p>
<video #myVideo></video>
ignore the video thing, everything works except that the {{texttoken}} is not updated, it displays the same initial dummy data that I set in my app.component.ts:
import { Component, OnInit, ViewChild } from '#angular/core';
import { Subject } from 'rxjs/Subject';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
#ViewChild('myVideo') myVideo:any;
texttoken :any = 'initial dummy value';
targetpeer: any;
peer: any;
n = <any>navigator;
ngOnInit() {
let video = this.myVideo.nativeElement;
let peerx: any;
let onJSTokenChange = new Subject(); // create new observable to obsere any changes to assign a value to texttoken
onJSTokenChange.subscribe((value)=>{
this.texttoken = value;
console.log(this.texttoken);
});
this.n.getUserMedia = (this.n.getUserMedia || this.n.webkitGetUserMedia || this.n.mozGetUserMedia || this.n.msGetUserMedia);
this.n.mediaDevices.getUserMedia({video:true, audio:true}).then( function(stream) {
peerx = new SimplePeer ({
initiator: location.hash === '#init',
trickle: false,
stream:stream
})
peerx.on('signal', function(data) {
console.log(JSON.stringify(data));
// here I pass that data to the observable
onJSTokenChange.next(JSON.stringify(data));
this.targetpeer = data;
})
peerx.on('data', function(data) {
console.log('Recieved message:' + data);
})
peerx.on('stream', function(stream) {
video.src = URL.createObjectURL(stream);
video.play();
})
}, function(err){
console.log('Failed to get stream', err);
});
}
connect() {
this.peer.signal(JSON.parse(this.targetpeer));
}
message() {
this.peer.send('Hello world');
}
}
here you can see that I assigned the dummy data to my texttoken , than I create an observable onJSTokenChange to track if something changes to assign a value to texttoken , this observable gets data from peerx.on('signal' code when ever it executes and then the onJSTokenChange.subscribe gets that data and console.log() the data which works as expected however the the.texttoken receives the value as well but it does not do the two-way binding and does not update <p>{{texttoken}}</p> even though I console.log() it and it returns the correct value , please help been trying to figure it out the whole day :(
I just imported ChangeDetectorRef from angular/core and injected
constructor(private detector:ChangeDetectorRef){}
used it in my
onJSTokenChange.subscribe((value)=>{
this.texttoken = value;
this.detector.detectChanges();
});
and it worked, thanks to #AJT_82 and #LLai