I'm using jQuery for some things in my angular2 projects. But I can't manage to use variables I've declared in angular2 to use in jQuery. I have something like this:
export class AddExerciseComponent implements OnInit {
parameters:Array<string> = ["FU"];
constructor() { }
ngOnInit() {
$('.chips').on('chip.add', function(e, chip){
this.parameters.push(chip.data);
console.log(this.selectedValue);
});
}
This would get me an error that parameters is not defined. I guess it's because I use this. What else can I do?
You need to use an arrow function expression (() => {}) to keep this in scope. Try:
export class AddExerciseComponent implements OnInit {
parameters:Array<string> = ["FU"];
constructor() { }
ngOnInit() {
// removed function keyword and added () => {} syntax
$('.chips').on('chip.add', (e, chip) => {
this.parameters.push(chip.data);
console.log(this.selectedValue);
});
}
When you passed your callback as a regular old function, JavaScript doesn't consider your callback to be within the scope of the calling function, leaving this unusable for calling data from the scope you thought you were in. By using an Arrow function, the scope is saved and this is usable for accessing data as expected.
If you are looking to use angular variables in jquery animate ON-Complete function call back,that's how you do it:
$('#myDiv').animate({top: 70+"%"},{
queue: false,
duration: 1000,
complete: () => {
//this is you angular variable of the class
this.angularVar = 0;
$("#myDiv").hide();
//this is you angular variable of the class
this.showAnimation = false;
//this is you angular class function
this.angularFunction();
console.log("animation complete");
}
});
Assign angular's this(instance) to Jquery's this(instance) to use the angular variable inside JQuery
let jQueryInstance = this; // This line will assign all the angular instances to jQueryInstance variable.
$('.chips').on('chip.add', (e, chip) => {
/* this.parameters.push(chip.data); */
// Instead of the above line we have to use like below
jQueryInstance.parameters.push(chip.data); // instead of "this", "jQueryInstance" is used
// console.log(this.selectedValue);
console.log(jQueryInstance.selectedValue);
});
Related
I am working on a task where I have an event listener window.addEventListener which is in javascript, based on event data I want to trigger a function of typescript and pass the data to that function. the point I am not getting is how to call typescript function in javascript. I have tried different things like a global variable, returning a value from js function but didn't work for me.
ngOnInit() {
(function ($) {
$(document).ready(function () {
window.addEventListener('message', function (event) {
console.log("Rece new Call event ibrahim " + JSON.stringify(event.data));
let obj: any = JSON.stringify(event.data)
obj = JSON.parse(obj);
console.log(obj)
if (obj.EventType === "handleContactIncoming") {
var num = obj.Number
// here i want to trigger Typescript function and pass this num to that function.
}
else if (event.data === "endCall") {
// return "No"
// var dbBtn = document.getElementById("db");
// dbBtn.click();
}
// $('.sidebar-menu').tree();
});
});
});
There is no difference when calling function from TS or JS. Finally there's always only JS in the browser, TS exists only in source code.
Also your code is a bit messy. There's no need to use jQuery inside angular (with an exception when you want to use some plugins or custom controls).
$(document).ready(function () {
is also redundant, if angular works the document is for sure ready.
Your code is quite messy and breaks separation of concerns. You should not use jQuery inside Angular. The injectable EventManager provides functionality for setting events on the window or document objects.
constructor(private readonly eventManager: EventManager) {}
ngOnInit(): void {
this.eventManager.addGlobalEventListener(target, event, () => {
this.hello();
});
}
hello(): void {
console.log('Hello World!');
}
I have variable called tableIndexNumber that i need use inside diffrent methodts. So when i try to reach that variable i use "this.tableIndexNumber" and i can reach it. But i cant use it this way inside Jquery each loop because of htmlElemets define as "this" too inside the each loop. So which way should i follow ?
export class TablesComponent implements OnInit {
tableIndexNumber = 1;
constructor() { }
change(col: number) {
$('#' + col).each(function () {
if ($(this).attr('class') === 'box') {
$(this).addClass('boxSelected');
this.tableIndexNumber ++;
} else {
$(this).removeClass('boxSelected').addClass('box');
}
});
}
The old school way of handling this was to save this to a variable before the each called "context" or "that" or something like that, and then using that variable. Thankfully today we have arrow functions, which are perfect for this situation since they do not have their own this context.
UPDATE: I neglected to look up the syntax for each. Looks like you need the internal this, so an arrow function won't work. Instead, you can solve your problem by saving the outer this to a variable:
export class TablesComponent implements OnInit {
tableIndexNumber = 1;
constructor() { }
change(col: number) {
const component = this;
$('#' + col).each(function() {
if ($(this).attr('class') === 'box') {
$(this).addClass('boxSelected');
component.tableIndexNumber++;
} else {
$(this).removeClass('boxSelected').addClass('box');
}
});
}
}
I have problems with jQuery callbacks
I try to do like this.
MainController.js
mapController = $.fn.mapController();
getMapController = function() {
return mapController;
};
mapController.js
(function ( $ ) {
$.fn.mapController = function(options) {
let mapController = {};
let settings = $.extend({
save: function(data) {}
}, options);
mapController.openModal = function () {
//OPEN MODAL
}
return: mapController
}
}(jQuery));
nextController.js
function setPlace() {
getMapController({
save: function(data) {
console.log("TEST")
}
}).openMapModal();
}
So... I try get mapController in nextController from getMapController method but not workink callbacks...
How I can get callbacks in nextController.js?
It seems like you have introduced some confusion by naming a jQuery plugin with the same name as the object that plugin returns. Both are called mapController. This is not a problem on itself, but in setPlace you call mapController as if it it is the jQuery plugin (passing it options), but it is in fact the object returned by it (see MainController.js), which is not a function.
So I think you'll want to change the MainController code, and make the global mapController variable equal to the jQuery plugin:
mapController = $.fn.mapController;
// ^^^^^ remove parentheses.
Like mentioned already, make sure to remove the syntax error in the return statement in the MapController; it should not have a colon after it.
getMapController() returns a function, you have to call it with ():
function setPlace() {
getMapController({
save: function(data) {
console.log("TEST")
}
})().openMapModal();
}
Also, you have an erroneous : on this line:
return: mapController
It should just be:
return mapController
I am using angular2 with typescript and i have defined a class
export class Example{
//.../
const self: all = this;
functionToCall(){
//.. Do somerthing
}
mainFunctionCall(){
somepromise.then(x => self.functionToCall('url/'+ x.name ) )
}
}
But it keeps throwing error about functionToCall being undefined.
Im quite new to typescript/angular#
is there any rule that prevents this to be correct? Or what is the correct way to invoke method of class inside another method ?
No need for such a hack here, since lambda functions capture the this reference of the outer scope. You can just simply write:
const somepromise = Promise.resolve({name:"noone"});
class Example {
functionToCall(x : string) {
console.log(x);
}
mainFunctionCall() {
somepromise.then(x => this.functionToCall('url/'+ x.name ) )
}
}
(new Example()).mainFunctionCall();
Edit Code snippet updated to include all details. Can be run in the typescript playground.
I was trying to implement an interface like architecture in JS as followed in C#. And met with a stumbling block. Here is the code sample:
// Interface for UIBuilder classes
function IUIBuilder() {
this.addUserToList = function () {
alert('parent: added');
};
}
// Class implementing the IUIBuilder
function ChatUIBuider() {
IUIBuilder.prototype.addUserToList = function () {
alert('child: added');
};
IUIBuilder.prototype.removeUserFromList = function () {
alert('child: removed');
};
return new IUIBuilder();
}
In the first class, I've defined a method addUserToList which I override in the second class ChatUIBuider. Also added one more method removeUserFromList to the base class using its prototype.
My issue is, the addUserToList method still invokes the parent class method even after it has got overridden in the child class. Why?
var builder = new ChatUIBuider();
builder.removeUserFromList(); // Invokes the child class method. - CORRECT
builder.addUserToList(); // Invokes the base class method- WHY??
Could anyone tell me if this is the correct way I am doing?
I suggest this construct :
function IUIBuilder() {
};
IUIBuilder.prototype.addUserToList = function () {
alert('parent: added');
};
// Class extending the IUIBuilder
function ChatUIBuider() {
}
ChatUIBuider.prototype = new IUIBuilder();
ChatUIBuider.prototype.addUserToList = function () {
alert('child: added');
};
ChatUIBuider.prototype.removeUserFromList = function () {
alert('child: removed');
};
ChatUIBuider extends IUIBuilder and inherits its functions but overrides the addUserToList function.
In the following code, both constructors will be called but only the overriding addUserToList function will be called :
var chat = new ChatUIBuider();
chat.addUserToList();
See demonstration
#Denys restructured the entire code , without exactly pointing out the issue. issue is addUserToList is not a prototype method of your parent class , it's a this method which is copied for every instance and not sahred. So just converting it to a prototype method fixes the issue.
// Interface for UIBuilder classes
function IUIBuilder() {
}
IUIBuilder.prototype.addUserToList = function () {
alert('parent: added');
};
// Class implementing the IUIBuilder
function ChatUIBuider() {
IUIBuilder.prototype.addUserToList = function () {
alert('child: added');
};
IUIBuilder.prototype.removeUserFromList = function () {
alert('child: removed');
};
return new IUIBuilder();
}
var builder = new ChatUIBuider();
builder.removeUserFromList(); // Invokes the child class method. - CORRECT
builder.addUserToList(); // Invokes the CHILD CLASS's METHOD