When I'm in the flash debugger, and I have some callbacks saved, I can see that the functions have a property named savedThis that is very usefull to know where that callback came from.
I'm trying to access that property from code, but for some reason I can't.
callback.savedThis throws an Error because it can't find the property, probable because it's private.
So I tried to add a method to the Function class that would give me access to it:
Function.prototype.getSavedThis = function()
{
return this.savedThis
}
But it gives me the same error about not finding the property, even though I can see it in the debugger.
Is there a way to access it?
Note: I'm not planing on using this in production code, I'm making some classes to help me with debugging by automating some data gathering, and it would be incredible useful to get this information without having to add code to every callback saved informing of the this object.
You can get a reference to a calling function by using the 'arguments.callee' property.
For example:
bar( arguments.callee );
public function bar( caller:Function ) : void { trace( caller ); }
Related
I'm a beginner in Ionic and Firebase. To learn using ionic+firebase, I'm writing a RandomQuote app to fetch a random entry from Firebase. A reload() method is called when I click a reload button, and the random quote is displayed as expected.
However, I also want the quote to display when the app is loaded, i.e., before I click the reload button. I call the reload() method in the constructor but it doesn't work. I have tried to search for answers on the web but cannot find anything that I could understand. Not sure if I'm searching the wrong keywords or in the wrong domains.
The following is the reload() method that I put in my FirebaseProvider class and called from my home.ts:
reload(){
this.afd.list('/quoteList/').valueChanges().subscribe(
data => {
this.oneQuote = data[Math.floor(Math.random() * data.length)];
}
)
return this.oneQuote;
}
Can anyone give me some hints? Or any pointer to useful books / materials for beginners will also be highly appreciated. Thank you very much.
Data is loaded from Firebase asynchronously. This means that by the time your return statement runs this.oneQuote doesn't have a value yet.
This is easiest to say by placing a few log statements around your code:
console.log("Before subscribing");
this.afd.list('/quoteList/').valueChanges().subscribe(
data => {
console.log("Got data");
}
)
console.log("After subscribing");
When you run this code, the output is:
Before subscribing
After subscribing
Got data
This is probably not what you expected. But it completely explains why your return statement doesn't return the data: that data hasn't been loaded yet.
So you need to make sure your code that needs the data runs after the data has been loaded. There are two common ways to do this:
By moving the code into the callback
By returning a promise/subscription/observable
Moving the code into the callback is easiest: when the console.log("Got data") statement runs in the code above, the data is guaranteed to be available. So if you move the code that requires the data into that place, it can use the data without problems.
Returning a promise/subscription/observable is a slightly trickier to understand, but nicer way to doing the same. Now instead of moving the code-that-needs-data into the callback, you'll return "something" out of the callback that exposes the data when it is available. In the case of AngularFire the easiest way to do that is to return the actual observable itself:
return this.afd.list('/quoteList/').valueChanges();
Now the code that needs the quotes can just subscribe to the return value and update the UI:
reload().subscribe(data => {
this.oneQuote = data[Math.floor(Math.random() * data.length)];
}
A final note: having a reload() method sounds like an antipattern. The subscription will already be called whenever the data in the quoteList changes. There is no need to call reload() for that.
I have to add a control inside a changeCompany() in an existing class.
I suppose the code below is OK, but I have a doubt : Does the "return" order imply that a return to the original company is done ?
Or is there to add a statement, unknown by me, something like revertToPreviousCompany()?
try
{
changeCompany(companyId)
{
// the method will produce a message and return false if an error
if (!this.doSomeChecks()) {
return;
}
// much more code below
Yes that is OK as in some situations you wouldn't even be able to revert it if not done by the runtime itself.
Imagine a callstack in which you have try - catch around some code your are calling and you expect there may be thrown an error but if the code which calls your code already established a transaction your handler is not called and therefore you wouldn't have a chance to undo the changeCompany
I added a new method to the CustVendPaym class called sendersBankCompanyStatementName of type BankCompanyStatementName.
This is the code of said method:
public BankCompanyStatementName sendersBankCompanyStatementName(BankCompanyStatementName _sendersBankCompanyStatementName = sendersBankCompanyStatementName)
{
sendersBankCompanyStatementName = _sendersBankCompanyStatementName;
return sendersBankCompanyStatementName;
}
I added the definition in the classDeclaration method:
BankCompanyStatementName sendersBankCompanyStatementName;
Then in the method vendPaym in the VendOutPaym class, a new instance of VendPaym (which extends CustVendPaym) is created:
vendPaym = new VendPaym();
//A bunch of properties are set then one I created:
vendPaym.sendersBankCompanyStatementName (bankAccountTable.BankCompanyStatementName);
If I break there, I see the assignment with the value I'm expecting working correctly, but then the debugger (watch) never actually shows the new property I added with the value that's supposed to be in it.
Then if I just continue code execution, the AOS server in which I'm developing just crashes :|
Any ideas, am I doing something obviously wrong ?
Thanks.
EDIT: If I rollback my changes (that is deleting the newly added method and removing any references to it) everything works as it was before.
Have you compiled forward the CustVendPaym class?
Recently, I suddenly began getting the current exception being thrown from a Flex library. The file I was working on (Login.mxml) suddenly began throwing up this exception while loading.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at mx.binding::StaticPropertyWatcher/updateParent()[E:\dev\4.x\frameworks\projects\framework\src\mx\binding\StaticPropertyWatcher.as:150]
at _components_LoginWatcherSetupUtil/setup()
at components::Login()[C:\Users\username\Documents\MP_MAIN\src\components\Login.mxml:0]
<snip ...>
at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\4.x\frameworks\projects\framework\src\mx\managers\LayoutManager.as:700]
at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\4.x\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1072]
Running it in the debugger doesn't give me a line of my code that is in error, but it does give me a line in StaticPropertyWatcher. Specifically:
override public function updateParent(parent:Object):void
{
// The assumption is that parent is of type, Class, and that
// the class has a static variable or property,
// staticEventDispatcher, of type IEventDispatcher.
parentObj = Class(parent);
if (parentObj["staticEventDispatcher"] != null) /* Exception thrown from here */
{
...
The debugger shows the parentObj is indeed null, explaining the immediate reason for the exception, but I can't seem to determine the deeper cause (i.e. what I did wrong). The updateParent method is being called from the _components_LoginWatcherSetupUtil class, but the debugger says there is no code for that, so the crucial connection between what I wrote and what caused the exception is missing.
So, basically, I can't even debug this. Any ideas for what to do to shed light on what's going wrong?
Your error is being reported as Login.mxml:0
When I see line 0 as the error it tells me that there is a syntax error of some sort. Open string maybe?
I would suggest looking at the file and see if it is set up properly.
Post the full Login.mxml file and let us look at it.
After laboriously adding back every change I made since last committing to my repository, I tracked down the culprit to this problem. Basically, there were several static variables used to keep track of server addresses like this:
public static var MAIN:String = "http://192.168.1.1/";
public static var MANAGE:String = MAIN + "Manage/";
The issue was that I used a non-compile-time constant MAIN to initialize MANAGE. Changing these variables to const fixed the problem.
public static const MAIN:String = "http://192.168.1.1/";
public static const MANAGE:String = MAIN + "Manage/";
Hopefully this will help anyone else coming across this problem
I am developing an application in GWT as my Bachelor's Thesis and I am fairly new to this. I have researched asynchronous callbacks on the internet. What I want to do is this: I want to handle the login of a user and display different data if they are an admin or a plain user.
My call looks like this:
serverCall.isAdmin(new AsyncCallback<Boolean>() {
public void onFailure(Throwable caught) {
//display error
}
public void onSuccess(Boolean admin) {
if (!admin){
//do something
}
else{
//do something else
}
}
});
Now, the code examples I have seen handle the data in the //do something// part directly. We discussed this with the person who is supervising me and I had the idea that I could fire an event upon success and when this event is fired load the page accordingly. Is this a good idea? Or should I stick with loading everything in the inner function? What confuses me about async callbacks is the fact that I can only use final variables inside the onSuccess function so I would rather not handle things in there - insight would be appreciated.
Thanks!
Since the inner-class/ anonymous function it is generated at runtime it needs a static memory reference to the variables it accesses. Putting final to a variable makes its memory address static, putting it to a safe memory region. The same happens if you reference a class field.
Its just standard java why you can only use Final variables inside an inner-class. Here is a great discussion discussing this topic.
When I use the AsyncCallback I do exactly what you suggested, I fire an event though GWT's EventBus. This allows several different parts of my application to respond when a user does log in.