Java script how to pass around an object with event being attached - javascript

I have a custom object that being passed around. I want to show a toast when a workflow is done.
I am looking for some thing like
object.addEvent("workflowIsDone", ()=> {
toast.open();
});
and when the workflow ends:
object.fireEvent("workFlowIsDone")
I was wondering if some one can tell me how to do it in Javascript

You might add a method to your object:
object.workflowIsDone = () => toast.open();
and call it when the workflow ends:
object.workFlowIsDone()

You can produce new events by using const myEvent = new Event('eventName')
And then add a listener to it:
element.addEventListener('eventName', function () { // ... })
Also you need to dispatch it:
element.dispatchEvent(myEvent)
For passing custom data there's a CustomEvent class that you can use. You can read more about it here

Related

send data to function using event handler (.on) in fabric js

As the title explain, i'm trying to send data to a function by event handler.
i've tried the following:
canvas.on("mouse:wheel",{name:"spin"}, constructSpin);
function constructSpin(e){
console.log(e.data.name);
}
sadly this is not working :(
is there any way to send data to a function using event handler ?
NOTE: i've found this in fabric document:
on(eventName, handler) → {Self}
so it look like there is no data in on construction !
You should construct and call the constructSpin function in the following way, if you wish to pass some custom data on mouse:wheel event :
canvas.on("mouse:wheel", function(e) {
constructSpin(e, { name: "spin" });
});
function constructSpin(event, data) {
console.log(data.name);
}
The fabric events are sort of syntetic.
You are spinning the wheel on the canvas element and you get back 2 events, one at canvas level and one at object level.
if spin is a particular object on your canvas, or is a name property of your objects you can have:
canvas.on("mouse:wheel", function(opt) {
// opt.e => real event
// opt.target => object where you spinned over
// opt.target.name maybe is what are you looking for
});
If my assumption is wrong, you can just do what is already suggested in another answer:
canvas.on("mouse:wheel", function(opt) {
// opt.e => real event
// opt.target => object where you spinned over
opt.name = 'spin'
yourFunction(opt);
});

Delegating a function call in Javascript

Is there a way in Javascript to have a delegate like the ones in c# ?
Example in c#
Object.onFunctionCall = delegate (vars v) {
Console.WriteLine("I can do something in this private delegate function");
};
I would like with my Javascript to have my main object do something over a long time, and shot a delegate once in a while to give a little update. All that without having to change the code itself of my class to adjust for the webpage.
function mainObject() {
this.onUpdate = function() { //Potentially the delegate function here
}
}
var a = new mainObject();
a.onUpdate = Delegate {
$(".myText").text("Just got a delegate update");
}
I dunno if it's clear enough.. havent found ressources on this so I suppose there is just no way to do so ?
NOTE: I am not looking into jquery Click delegates event here, but into delegating a function call like how it works in c#
Let me know
Although the original question was ansered by solving the root problem (observer - pattern) there is a way to implement delegates in JavaScript.
The C# delegate pattern is available in native JavaScript using context binding. Context binding in JavaScript is done with the .call method. The function will be called in the context given by the first argument.
Example:
function calledFunc() {
console.log(this.someProp);
}
var myObject = {
someProp : 42,
doSomething : function() {
calledFunc.call(this);
}
}
myObject.doSomething();
// will write 42 to console;
What you are looking for is an "Observer Pattern", as described eg. here.
But as you are interested in jQuery, you don't need to go the trouble of writing an observer pattern for yourself. jQuery already implements an observer in the guise of its .on() method, which can be invoked on a jQuery collection to cause callback function(s) to fire every time a native or custom event is dispatched.
Here's an example :
$(function() {
//attach a custom event handler to the document
$(document).on('valueChange', function (evt) {
$(this).find("#s0").text(evt.type);
$(this).find("#s1").text(evt.value);
$(this).find("#s2").text(evt.change);
$(this).find("#s3").text(evt.timestamp).toLocaleString();
});
//customEvent(): a utility function that returns a jQuery Event, with custom type and data properties
//This is necessary for the dispatch an event with data
function customEvent(type, data) {
return $.extend($.Event(type||''), data||{});
};
//randomUpdate(): fetches data and broadcasts it in the form of a 'changeValue' custom event
//(for demo purposes, the data is randomly generated)
function randomUpdate() {
var event = customEvent('valueChange', {
value: (10 + Math.random() * 20).toFixed(2),
change: (-3 + Math.random() * 6).toFixed(2),
timestamp: new Date()
});
$(document).trigger(event);//broadcast the event to the document
}
});
Here's a demo, complete with "start" and "stop" buttons for a regular "interval" dispatch of the custom event.
Notes
Under some circumstances, it might be more appropriate to broadcast the event to the four data spans individually.
On the web, you will find mention of a more convenient jQuery.event.trigger({...}) syntax. Unfortunately this was an undocumented feature of jQuery, which disappeared at v1.9 or thereabouts.

Sending data from classes?

I'm looking into deferred and custom events. I'm not sure what method would suit my application.
I have a class that calls another class. Inside this class a user can drag files on to the window.
Once the file has been dragged on, I wish to send details about the files to my main class.
I've thought about using deferred, but the user needs to drag files over and over again, and as of my understanding this can only be used once.
So in my main class I:
this.dropBox = new DropBox();
Then in the DropBox class I have:
$(window).on('drop', this.drop);
But what should I put in my 'drop' method. Every time something is dropped I wish to 'alert' my main class about it and act upon it. How can I 'listen' for the event. Should I use deferred, custom event or something else?
There are typically two options for this:
Delegate
A delegate should implement a certain "interface", a set of functions that handle certain events.
function DropBox(delegate)
{
this.delegate = delegate;
$(window).on('drop', $.proxy(this, 'drop'));
}
DropBox.prototype.drop = function(e) {
// do stuff with event
this.delegate.drop(e);
}
// inside main instance
this.dropBox = new DropBox(this);
// delegate interface
this.drop = function(e) {
// handle file drop
};
Callback
If the delegate only needs one function, you can use a callback as well:
function DropBox(dropEventHandler)
{
this.dropEventHandler = dropEventHandler;
$(window).on('drop', this.drop);
}
DropBox.prototype.drop = function(e) {
this.dropEventHandler(e);
};
// inside main instance
var self = this;
this.dropBox = new DropBox(function(e) {
// handle file drop
// use 'self' to reference this instance
});
Why not just give a callback over to the DropBox?
Well, like this code in the main class:
this.dropBox = new DropBox(function(fileInfo) {
// this code can be executed by the DropBox Object multiple times!
});
And the DropBox:
window.DropBox = function(callback) {
this.userHasDroppedFiles = function(fileinfo) {
// do stuff
callback(fileinfo); // give the fileinfo back with the callback!
}
}
Also, there are no classes in JavaScript! You have only Objects, and you can use constructor-functions combined with prototypes to generate a class like behaviour, but you will never actually have classes like in Java, C# or similar languages. Keep this always in mind.
Some JS frameworks build their own class layer on top of the main JS possibilities, then you may have Framework classes, but also never native JavaScript classes, because native JavaScript classes dont exist!

Dispatch custom Event to a JS object

I have a object Constructor that I want to dispatch a customEvent from. Then I want to listen to it from the instance of the object.
The code below is an example of what I'm trying to accomplish. Anyone know how or if this is possible.
var example = new Example();
example.addEventListner('customEvent', tempMethod);
function tempMethod(event){
console.log("event working = ", event.message);
}
function Example(){
// dispatch and event from here.
this.dispatchEvent('customEvent', 'message hello');
}
You can use jQuery to create an emitter from a plain object (or from your Example instance).
var emitter = $({});
$(button).click(function() {
emitter.trigger('customEvent');
});
You could also use an emitter library like energy or eventemitter2.
var emitter = energy();
button.addEventListener('click', function() {
emitter.emit('customEvent');
}, false);
Without the button (as in your edited question) you can create your own .on, .off, and .emit methods on your Example.prototype or you can assign them from an emitter instance like this.

Javascript custom events object for another object?

I am making a custom events object so that I can inject custom events into another object, so far I have (simplified),
function Game() {
new Events(["pause", "resume"], this);
};
function Events(events, obj) {
// Event object for object
obj.events = {};
// For each event
events.forEach(function(event) {
// Attach event array to store callbacks
this.events[event] = [];
}, obj);
// Fire event
obj.fire = function(event) {
////////////
};
// Add event
obj.on = function(event, callback) {
////////////
};
};
My question is, is this the right way to do this? Is it considered ok to call Event from Game and add to Game from Events? It for some reason seems wrong to me, and I do not know why?
Is there any way that I should be structuring this code that I am not aware of?
(I do not want to add Events to Game's prototype for the sole reason that Game has events and is not an extension of Events)
Thank you for taking the time to read my question.
My question is, is this the right way to do this? Is it considered ok to call Event from Game and add to Game from Events?
Yes, it's perfectly fine. This is called the decorator pattern. I don't see a reason for your feeling that it was wrong.
Is there any way that I should be structuring this code that I am not aware of?
Don't use new. Events is not a constructor. A better and more descriptive signature might be
function makeEventEmitter(obj, events) {

Categories