issue with this when two classes in one function [duplicate] - javascript

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 2 years ago.
I have two classes in a function and for some reason in the second function this is not being recognised correctly.
The classes are Emitter and Receiver.
I am trying to figure out why this is not being picked up correctly here. The log is included in the code below:
const chat = (messages) => {
class Emitter {
constructor(messages = []) {
this.messages = messages;
this.event = () => {};
}
setEvent(fn) {
this.event = fn;
}
trigger() {
this.messages.forEach(message => this.event(message));
}
}
class Receiver {
constructor() {
this.messages = [];
// this prints correctly here
---> Receiver { messages: [] }
console.log('this ===> ', this)
}
ping(message) {
console.log('this ===>', this)
// this here prints the following
this ===> Emitter {
messages: [ 'Hi', 'Hola', 'Bonjour', 'Hi' ],
event: [Function: ping] }
this.messages.push(message);
}
}
const myReceiver = new Receiver();
const myEmitter = new Emitter(messages);
myEmitter.setEvent(myReceiver.ping);
myEmitter.trigger();
return myReceiver.messages;
};

The this depends on the scope where it is called but not the scope it is defined.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
In the call myEmitter.setEvent(myReceiver.ping), only the function ping is passed to the myEmitter, not its scope myReciever. In case if you would like to pass myRevciever scope you can bind it the function call.
myEmitter.setEvent(myReceiver.ping.bind(myReceiver));

Related

Accessing the name of the function when multiple functions are returned

I have a basic function, that can be called around my project using different names - tiger, lion, dog.
I'd like to access the name of the triggered name within the function its self.
For example:
I can run demo.tiger('Hello', {1:1}) and like to access the tiger name from within the trigger function.
Thanks
const demo = ({ }) => {
function trigger (message, context) {
console.log(message, context);
}
return {
tiger: trigger,
lion: trigger,
dog: trigger
}
}
As #Barmar suggested, you have to pass it through as an argument if you really want it.
const demo = () => {
function trigger(message, context, caller) {
console.log(message, context, caller);
}
return {
tiger: (message, context) => trigger(message, context, 'tiger'),
lion: (message, context) => trigger(message, context, 'lion'),
dog: (message, context) => trigger(message, context, 'dog'),
};
};
const x = demo();
x.tiger('a', { 1: 1 });
x.lion('a', { 1: 1 });
x.dog('a', { 1: 1 });

Catching an event from an a class which inherits EventEmitter using es6 classes

I'm new to Javascript and es6. I am attempting to catch an event emitted by an object which is an ecmascript-6 (es6) class called LaserHandler, that inherits EventEmitter. My listener is present in an object which is also an es6 class object called QRMarker, that instantiates the object. This is on nodejs not browser is used.
I expect to see the callback function of the of the listener to be called. The listener is not fired. There is no indication of error.
So I tried various alternate coding approaches including 1) using the 'event-emitter-es6' npm module. 2) rewriting to use const events = require('events').EventEmitter and extending events. 3) Varying the location of the listeners, emits, and where the class is instantiated.
The result of console.log (qrMarker): In the following code is:
QRMarker {
domain: null,
_events:
{ stationId: [ [Function: listener], [Function] ],
'*': [Function] },
_eventsCount: 2,
_maxListeners: undefined,
id: undefined }
const EventEmitter = require('event-emitter-es6');
/LaserHandler.js/
let qrMarker;
module.exports = class LaserHandler extends EventEmitter {
constructor(s, l) {
super();
logger = l;
socket = s;
qrMarker = new QRMaker(this.logger);
}
manageLaser() {
qrMarker.communication(socket);
socket.on ('LaserDown', () => {
console.log('LaserHandler.manageLaser: received event'
)});
qrMarker.on('stationId', (data) => {console.log(data)} );
qrMarker.on('*', (data) => {console.log ('Caught event !!!')});
}
}
/*end of file*/
/* QRMarker.js */
module.exports = class QRMarker extends EventEmitter {
constructor(l, id) {
super();
logger = l;
this.id = id;
}
communication(s) {
let connected = false;
let socket = s;
let dataBuffer;
let lastStatusCode;
this.emit( 'stationId', stationId);
dataBuffer = Buffer.from(data);
connected = true;
}
}
}
/* end of file */
/* LaserService */
module.exports = class LaserService {
constructor () {
}
startNeworking () {
server = net.createServer();
server.on('connection', function (socket) {
let laserHandler = new LaserHandler(socket, logger);
laserHandler.manageLaser();
});
server.listen(41020, function () {});
}
}
/*end of file */
/*TestLaserService -- this file is executed from node */
var LaserService = require("../LaserService.js");
let laserService = new LaserService(2);
laserService.startNeworking();
/* end of file*/
Thank you.

VueJS returns undefined in created function [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 3 years ago.
i have started working on a small project using VueJs, i've made a get request using Axios library which returns some data as expected, but I cannot call loadUsers function using this inside mounted
this is my code:
export default{
data(){
return {
users : {}
}
},
methods:{
addCustomer(){
//var form = document.querySelector('#add-customer');
var formData = $('#add-customer').serialize();
axios.post('/Thirdparty', formData).then(function(response){
helper.validation(response.data);
//alert(response.data.error);
});
},
loadUsers(){
axios.get('/Thirdparty/loadUsers').then(function(data){
this.users = data.data;
});
}
},
created(){
let self=this
self.loadUsers();
}
}
as you can see also i've used self variable to call my loadUsers() function, but i'm still getting
this is undefined error
You're referencing this.users within the callback to axios.get().then() in loadUsers(). Due to you're using a standard function and not an arrow function, this is not referring to the Vue instance, i.e. the scope for this is now incorrect. Either use an arrow function or change the reference:
// Do this...
export default{
data(){
return {
users : {}
}
},
methods:{
addCustomer(){
//var form = document.querySelector('#add-customer');
var formData = $('#add-customer').serialize();
axios.post('/Thirdparty', formData).then(function(response){
helper.validation(response.data);
//alert(response.data.error);
});
},
loadUsers(){
axios.get('/Thirdparty/loadUsers').then((data) => { // Using an arrow function.
this.users = data.data;
});
}
},
created(){
let self=this
self.loadUsers();
}
}
// Or this...
export default{
data(){
return {
users : {}
}
},
methods:{
addCustomer(){
//var form = document.querySelector('#add-customer');
var formData = $('#add-customer').serialize();
axios.post('/Thirdparty', formData).then(function(response){
helper.validation(response.data);
//alert(response.data.error);
});
},
loadUsers(){
let self=this; // Adding "self"
axios.get('/Thirdparty/loadUsers').then(function(data){
self.users = data.data; // Referencing "self" instead of "this".
});
}
},
created(){
let self=this
self.loadUsers();
}
}

this.setData is not a function in react [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 3 years ago.
I am getting this weird issue in facebook login where I get the response but after getting the response, I am not able to dispatch actions.
Therefore, I wrote a function to do this but I am getting this.setData is not a function.
testAPI() {
window.FB.api('/me' ,function(response) {
console.log("testAPI",response);
if(response){
userProfile = {
access_token:accessToken,
id:response.id,
name:response.name,
provider: "Facebook",
};
console.log("userProfile",userProfile);
this.setData(userProfile);
}
console.log('[FacebookLoginButton] Successful login for: ', response);
});
}
setData = userProfile => {
this.setState(
{
userData: userProfile
},
() => {
console.log("inside setData");
if (userProfile !== undefined) {
console.log("inside callback", userProfile);
this.props.loginUser(this.state.userData);
}
}
);
};
This will help ( https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56 ) [ You need to bind function in order to set context of this ]
You have to use arrow function, or bind function to set correct context of this.
window.FB.api('/me', response => {
// function body
}

Javascript How to call another function within a variable object function [duplicate]

This question already has answers here:
How to call another function within the same object?
(2 answers)
Closed 4 years ago.
i want to call the isAuthenticated() method within the logout function.
(Im not sure what you call this layout its like a variable object containing functions)
var svc = {
logout: function () {
isAuthenticated() // Call isAuthenticated function here
},
login: function () {},
isAuthenticated: function () {}
}
Simply calling isAuthenticated() does not work.
svc is an object, where are logout & isAuthenticated are methods.You can use this to call the function.Here this points to the svc object
var svc = {
logout: function() {
this.isAuthenticated() // Call isAuthenticated function here
},
login: function() {
},
isAuthenticated: function() {
console.log('isAuthenticated called');
}
}
svc.logout()
Add this to it.
var svc = {
logout: function () {
this.isAuthenticated() // Call isAuthenticated function here
},
login: function (){
},
isAuthenticated: function () {
console.log("Test");
}
}
svc.logout();
I believe what you are looking for is:
this.isAuthenticated();
You need to use "this" to call other members of the same object.
Javascript object variables and functions are accessed by prefixing the object name followed by the variable/function name.
In your case, you can call isAuthenticated() like this:
svc.isAuthenticated()
You nee to use the reference of that object svc --> this.isAuthenticated()
var svc = {
logout: function() {
this.isAuthenticated()
},
login: function() {},
isAuthenticated: function() {
console.log("Is Authenticated!?")
}
}
svc.logout();
Another alternative is creating a function and declaring a variable, this way you will be able to call it directly as follow:
var svc = function() {
var isAuthenticated = function() {
console.log("Is Authenticated!?");
}
this.isAuthenticated = isAuthenticated;
this.logout = function() {
isAuthenticated()
};
this.login = function() {};
}
new svc().logout();
new svc().isAuthenticated();

Categories