Eladian Eladian - 14 days ago 4
Javascript Question

Javascript created object property values undefined after calling another function with created object

I know this may be a silly question but I'm new to javascript so would appreciate some guidance.

I have the following

notificationSocketEventHandler
object created:

const notificationSocketEventHandler = Object.create(socketHandlerProto, {
validators: {
created: [],
destroyed: [],
loadedFromSocket: [],
updated: [],
addedto: {
relation: []
},
removedfrom: {

}
},
created: function (data) {
if (this.validateProfileData(data, validators.created)) {} else {}
},
destroyed: function (data) {},
updated: function (data) {},
loadedFromSocket: function (data) {
console.log('Loaded from socket')
console.log(data)
}
})


This event handler is being used to listen for notifications from a socket
so and is set like this

$.globals.socket.on('notifications',notificationSocketEventHandler);


the event prototype is defined as such:

$.globals.socket = {
events: {},
on: function (attr, func) {
if (!attr) return false
this.events[attr] = this.events[attr] || [];
this.events[attr].push(func)
return true
},
remove(attr, func) {
if (!events[attr]) return false

this.events[attr].forEach(function (f, indx) {
if (f === func) {
events[attr].slice(indx, 1)
}
})
},
trigger: function (attr, thisArg, paramArgs) {
if (Array.isArray(attr) && attr.length) {
var obj = this.events[attr[0]]
for (var i = 1; i < attr.length; i++) {
if (!obj) return
obj = obj[attr[i]]
}
if (typeof obj == 'function') obj.apply(thisArg, paramArgs)
if (Array.isArray(obj)) {
obj.forEach(function (c) {
if (typeof c == 'function') c.apply(thisArg, paramArgs)
})
}
return
}
if(this.events[attr]){
console.log(this.events[attr])
this.events[attr].forEach(function (f) {
if (typeof f === 'function')
f.apply(thisArg, paramArgs)
})
}
}
}


The problem I am having is that after the
notificationSocketEventHandler
object gets passed to the
$.globals.socket.on
function and ultimately pushed into the events object, the properties of the
notificationSocketEventHandler
such as
created
,
destroyed
,
loadedFromSocket
which are defined as functions before being passed to the
$.globals.socket.on
function, suddenly become `undefined' once within the events object, why is this?

Answer

Object.create is a little confusing - you can't use a normal object as the second parameter, it has to be an object of 'property descriptors'. To work properly your code would need to be formatted along these lines:

const notificationSocketEventHandler = Object.create(socketHandlerProto, {
  'validators': {
    value: {
     'created': {
          value: []
      },
      'destroyed': {
          value: []
      },
      'loadedFromSocket': {
           value: []
      }
    }    
  }
});

Unless you iterate over those properties it's going to be tedious. You would be much better off avoiding Object.create and just making an object normally:

const notificationSocketEventHandler = {
   created: [],
   destroyed: [],...
}

or adding the properties to the constructor's prototype (as an aside, people usually make constructor names begin with an uppercase letter so it's immediately obvious they're constructors - saves you having to add 'Proto' at the end of the name for one thing. Anyway):

var SocketHandler = function {
    this.created = [];
    this.destroyed = []...
}

const notificationSocketEventHandler = new SocketHandler

or

var SocketHandler = {};
SocketHandler.prototype.created = [];
SocketHandler.prototype.destroyed = [];
etc...
Comments