JS/CoffeScript Call a method when an object is constructed - coffeescript

I have the following code
class MyCompo
constructor: (component) ->
#component = $(component)
#setEvents()
setEvents: ->
#component.on "click", #handleMyEvent
handleMyEvent: =>
...
that works just fine.
Now I need to fire handleMyEvent also when the object is constructed.
I have tried with DOMNodeInserted as follows
setEvents: ->
#component.on "DOMNodeInserted", #handleMyEvent
#component.on "click", #handleMyEvent
but I have some strange behavior (the method is called multiple times and not for all objects).
After further research, I found out that DOMNodeInserted even deprecated.
Is there an event that is fired when the object is constructed?
I know I could add it to the constructor itself but if possible I'd rather keeping everything on setEvents`.
Thanks

Related

Run function with Toast in Application Class

Thank you all so much! I just started in Kotlin which probably should be called the K language (like C and F), and have found so many solutions here on this site...it's awesome!
I have an independent class file called AppTime.kt and it's declared in the AndroidManifest.xml file:
<application
android:name=".AppTime"
class AppTime : Application() {
fun burntToast(sMsg: String) {
Toast.makeText(this.applicationContext, "!", Toast.LENGTH_LONG).show()
}
}
It doesn't run when called anywhere from a Fragment class:
class FirstFragment : Fragment() {...
AppTime().burntToast()
I've tried every approach using parameters for the Toast following makeText(...
and then to call it from a Fragment with or without context or string parameters.
Is it the type of class I have?
Functions defined inside a class can only be called on an instance of that class, as you already found.
But you cannot simply instantiate an arbitrary Application and expect it to work. Android does a lot of behind-the-scenes setup of framework classes before they are usable. Any Application or Activity that you instantiate yourself is useless. You have to use the instances that are provided to you through the lifecycle of the Activities that get launched in your application.
If you want to call this function from your Fragment, you will have to get an instance of your application, which you can get from its associated Activity. Since the Activity class doesn't know about your specific subclass of Application, you must also cast the application to your specific subclass to be able to call its unique functions. You can get the Activity by using requireActivity().
(requireActivity().application as AppTime).burntToast()

Typhoon loading storyboard programmatically appears to perform asynchronous instantiation without blocking

I am developing an iOS application and am trying to integrate Typhoon into the testing. I am currently trying to mock out a dependency in a view controller that comes from the storyboard, so with in my assembly:
public dynamic var systemComponents: SystemComponents!
public dynamic func storyboard() -> AnyObject {
return TyphoonDefinition.withClass(TyphoonStoryboard.self) {
(definition) in
definition.useInitializer("storyboardWithName:factory:bundle:") {
(initializer) in
initializer.injectParameterWith("Main")
initializer.injectParameterWith(self)
initializer.injectParameterWith(NSBundle.mainBundle())
}
}
}
I want to create a CameraModeViewController (the class I am unit testing) with its dependency upon a system-camera-functions-providing protocol mocked out. The dependency is dynamic var cameraProvider: CameraAPIProvider?. I think I correctly created a replacement collaborating assembly to replace systemComponents; MockSystemComponents is a subclass of SystemComponents that overrides functions. This is where I inject the mock:
let assembly = ApplicationAssembly().activateWithCollaboratingAssemblies([
MockSystemComponents(camera: true)
])
let storyboard = assembly.storyboard()
subject = storyboard.instantiateViewControllerWithIdentifier("Camera-Mode") as! CameraModeViewController
The next line of code in the tests is let _ = subject.view, which I learned is a trick to call viewDidLoad and get all the storyboard-linked IBOutlets, one of which is required for this test.
However, I am getting very mysterious result: sometimes but not always, all the tests fail because in the viewDidLoad I make a call to the dependency (cameraProvider), and I get an "unrecognized message sent to class" error. The error seems to indicate that at the time the message is sent (which is a correct instance method in protocol CameraAPIProvider) the field is currently a CLASS and not an instance: it interprets the message as +[MockSystemCamera cameraStreamLayer] as reported in the error message.
~~~BUT~~~
Here's the kicker: if I add a breakpoint between the calls to assembly.storyboard() and subject.view, the tests always pass. Everything is set up correctly, and the message is correctly sent to an instance without this "class method" bogus interpretation. Therefore, I have to wonder if Typhoon does some kind of asynchronous procedure in the injection that I have to wait for? Possibly only when dealing with storyboard-delivered view controllers? And if so, is there any way to make sure it blocks?
After digging around in Typhoon's source for a while, I get the impression that in the TyphoonDefinition(Instance Builder) initializeInstanceWithArgs:factory: method there is an __block id instance that is temporarily a Class type, and then is replaced with an instance of that type; and possibly this can be called asynchronously without blocking, so the injected member is left as a Class type?
UPDATE: Adding the code for MockSystemComponents(camera:). Note that SystemComponents inherits from TyphoonAssembly.
#objc
public class MockSystemComponents: SystemComponents {
var cameraAvailable: NSNumber
init(camera: NSNumber) {
self.cameraAvailable = camera
super.init()
}
public override func systemCameraProvider() -> AnyObject {
return TyphoonDefinition.withClass(MockSystemCamera.self) {
(definition) in
definition.useInitializer("initWithAvailable:") {
(initializer) in
initializer.injectParameterWith(self.cameraAvailable)
}
}
}
}
UPDATE #2: I tried replacing the constructor injection in the MockSystemComponents.systemCameraProvider() with a property injection. Different issue, but I suspect it's equivalent in cause: now, the property that is injected (declared optional) is still nil some of the time when I go to unwrap it (but not always -- probably about 4/5 of test runs fail, about the same as before).
UPDATE #3: have tried using the following code block, using factory construction according to this answer (note that setting factory directly didn't work as that OP did, but I think I correctly used the feature added in response to Jasper's issue). The results are the same as when using property injection like Update #2 above), so no dice there.
This issue was in fact arising even before the call to the instantiation. In fact, the problem was assemblies aren't generally intended to be stateful. There are a few ways to get around this, but the one I used -- having a member variable and an initializer method -- is NOT recommended. The problem with doing this is that in the activateWithCollaboratingAssemblies method, all the instance methods of the assembly are enumerated for definitions, and initializers will actually get called on the collaborating assembly. Consequently, even if you create your assembly with an initializer, it may get called again with a bogus value.
Note that the reason there appeared to be async behavior is actually that there is nondeterministic order in which definitions are assembled (property of storing them in an NSDictionary). This means that if activateWithCollaboratingAssemblies happens to enumerate methods which depend on state first, they'll work fine; but if the initializer is enumerated first, and the state is destroyed, definitions that are created after will be borked.

Difference between this and window

Imagine that coffeescript class :
class Batman
constructor: ->
alert "Batman is awesome"
I think it's a rookie question, but what's the real difference between :
class #Batman
constructor: ->
alert "Batman is awesome"
and
class window.Batman
constructor: ->
alert "Batman is awesome"
Compile your coffeescript using the '-c' argument and see what you get:
(function() {
/// Your code here
}).call(this);
That this there is the context of the function wrapper being called, and becomes the this object inside your coffeescript module.
In the context of a browser, your module is initialized with the global this = window; in the context of a Node or IoJS, this = global, the global context of execution; in the context of plv8, this = role, a per-execute object that contains security information (since plv8 is basically node run inside a SQL server, this is important to have).
class window.Batman explicitly attaches your Batman class to a window object (which means you no longer have isomorphic code you can use everywhere); class #Batman attaches it to the local context, which can be, well, whatever you want it to be.
All in all, as a best practice, attaching stuff to VM-supplied contexts (like the browser, your node instance, your database) is generally not a good idea, and you should find a better way to instantiate your code and pass it from module to module.

WinJS.Class.define() - refer to member function in constructor

I have a WinJS class defined as follows and would like to use a member function in the constructor:
WinJS.Class.define(
function() {
setInterval(myMemberFunction, 100);
},
{ // Member variables
myMemberFunction: function() {
// Do something
}
});
Unfortunately it looks like I can't resolve member functions in that manner in the constructor. This code all lives in a module so I could move myMemberFunction up the hierarchy and access it from the constructor, however the drawback is that "this" would no longer refer to the instance of my WinJS class. What's the recommended method for accessing instance members in a WinJS from the constructor?
Generally speaking, you refer to any method or property using "this," as in this.myProperty. In the case of event handlers, you need to make sure that the "this" that you see inside the handler is the instance "this". That's the purpose of the bind method of a function object. So you do this:
setInterval(this.myMemberFunction.bind(this), 100);
This makes sure that you bind the right "this" instance to the callback. Because I've seen this question pop up frequently (use of .bind is all over the Windows SDK samples), I wrote about this in more detail on http://www.kraigbrockschmidt.com/2012/11/28/purpose-function-dot-bind/.
Just to note, this is pure JavaScript; nothing particular to WinJS or Windows Store apps.

Assigning to a stub class method in Moles while using partial stubs

I've seen this question regarding partial stubs, but it does not quite tell me what I need to know.
I understand that, if I am using a Moles stub for a class (let's say, for DataService, I'm using SDataService), I can set the CallBase property to true so that, if there is no delegate for a particular method, the base implementation's method will be called. Great, but how do I assign a delegate to a particular method in this case?
If there is no way to do that, say I have an interface IDataService that I stub using SIDataService. I can easily assign a delegate to a method here. But, how do I tell it to call the corresponding method on DataService (an implementation of IDataService) if there is no delegate for a given method?
Thank you!
Edit:
I see now that the method needs to be virtual to be overridden in the first scenario above. I don't think that makes a whole lot of sense, but it is what it is.
So, focusing on the second scenario, would I have to create a Behavior? (And why isn't there one already for stubs like there is for moles?) Or is there a simpler way?
Delegates (detours) are set to stubs types the same way as mole types. For example, SIDataService.GetMemberProfile() is configured to return a mock object like this:
var memberMock = new Member() { Firstname="Joe", LastName="Schmoe" };
var stub = new SIDataService();
stub.GetMemberProfileMember = i => memberMock;