I'm experiencing a very weird behaviour out of onGenerateRoutes. So, I've this app in which a user is able to see the home screen if :
He signs in using the correct OTP for a phone number that's already registered. (case - '/checkUserDetails')
After he/she registers on the app. (case - '/verifyRegistration')
If he's already registered and reopening the app. (case - '/')
Now, to achieve this, I've created a Routes object which looks something like this:
Route routes(RouteSettings settings) {
switch (settings.name) {
case '/':
{
//Show OnboardingScreen or LoginScreen or HomeScreen based on user's app state
}
case '/checkUserDetails':
// Executed when user has submitted the received OTP
{
//Do something and return RegisterScreen or HomeScreen based on data received from the backend
}
case '/verifyRegistration':
//Executed when the user has submitted the registration form
{
//Verify the registration and send user to HomeScreen or ErrorScreen
}
}
Now, what happening is that If my code is on (let's say) - /verifyRegistration or even /checkUserDetails, before executing return HomeScreen(), the code will automatically go to case '/' of the switch statement and start executing the code from within there.
Now, this is a problem because my bloc class executes a certain set of functions before HomeScreen is rendered. Calls to those functions are mentioned inside all three of these routes (as user can go to the HomePage from either of them based on the 3 points I've mentioned above).
Since, my code is unexpectedly going to the case '/' (even when settings.name is /verifyUser or something else) It's making duplicate function calls which is resulting in unexpected data. Duplicate because those functions are being executed from within the expected route and the unexpected one as well (case '/')
Any idea how can I stop this from happening ?? Do you think that the switch statement has something to do with it ? I hope I was able to explain properly.
Thanks in advance!
Related
My app is in 2 parts. It creates a widget tree and populates a Stateful Widget Config.
I then pass this to phase 2 of my app as a static. (I tried various ways).
On a clean emulator it runs fine. When I run it again using Hot Restart my buildSitePath is passed a half-baked instance that did not go thru the proper constructors.
Thus where appCfg is a static Config appCfg
that has been confirmed to be populated properly the log statement in the following will execute after
the populating and yet it will be the half-baked instance that breaks the app. This happens on Hot Restart which supposedly restarts the app from the beginning.
routes:<String,WidgetBuilder>{
"/site":(BuildContext context) {assert(log("site: $appCfg"));
return buildSitePath(context,appCfg,title);}
},
The solution was to not use a static and to use a onGenerateRoute and pass the actual instance as a parameter. Thus, this worked.
onGenerateRoute: (settings) {
log("onGenerateRoute ${settings.name}");
if (settings.name == "/site") {
Config appCfg = settings.arguments;
log("onGenerateRoute $appCfg");
if (isMaterial(contextA)) {
return MaterialPageRoute(builder: (context) => buildSitePath(contextA, appCfg, title));
} else {
return CupertinoPageRoute(builder: (context) => buildSitePath(contextA, appCfg, title));
}
}
return null;
I looked and found no understanding as to what Hot Restart is doing with classes that might explain this.
What am I missing? Thanks.
As I said in my question my suspicion is that Flutter Hot Restart sees the static class instance that is not populated and jams the class in there using a default constructor.
Even if the class was not static but a member of another class the same ailment persisted.
I record this behavior here so that others need not waste as much time as I did to understand the problem.
In my application I need to wait until external program (using QProcess) is finished. I want to keep the application responsible so blocking methods are unacceptable.
Also I need to disallow user input. I've tried to make QEventLoop and exec it with QEventLoop::ExcludeUserInputEvents flag, but as documentation says it only delays an event handling:
the events are not discarded; they will be delivered the next time processEvents() is called without the ExcludeUserInputEvents flag.
So I implemented simple event filter and install it on qApp (the idea is took from Qt Application: Simulating modal behaviour (enable/disable user input)). It works well, but sometimes QApplication::processEvents function never returns even if I specify the maximum timeout. Could anyone help me to understand for what reasons it periodically happens?
class UserInputEater : public QObject
{
public:
bool eventFilter(QObject *object, QEvent *event)
{
switch(event->type())
{
case QEvent::UpdateRequest:
case QEvent::UpdateLater:
case QEvent::Paint:
return QObject::eventFilter(object, event);
default:
return true;
}
}
};
-
UserInputEater eventEater;
qApp->installEventFilter(&eventEater);
QProcess prc;
prc.start("...");
while(!prc.waitForFinished(10))
{
if(qApp->hasPendingEvents())
{
// Sometimes it never returns from processEvents
qApp->processEvents(QEventLoop::AllEvents, 100);
}
}
qApp->removeEventFilter(&eventEater);
UPD: Seems like it depends of the timeout value for QProcess::waitForFinished.
I guess you are filtering some useful events (for example, QEvent::SockAct could be involved). Try to add some debug output and find out which event types you're actually filtering. Or it might be better to specify the black list of events you want to block instead of white list of events you want to allow. See this answer.
Also you shouldn't use return QObject::eventFilter(object, event);. You should use return false. All other event filters will be called automatically.
This solution however seems weird and unreasonable to me because you can just call setEnabled(false) for your top level widget to block user input, and then you can use QApplication::processEvents without any flags.
I am wanting to know a button is rendered on main window UI or not. This button rendering is depending on server response result (written in Objective C). If server response comes perfectly it becomes render perfectly (VISIBLE) otherwise it is not present there (INVISIBLE). And whenever it becomes visible I always tap on it for further next process.
I wrote code
UIATarget.localTarget().pushTimeout(200);
//My code
UIATarget.localTarget().popTimeout();
By the above code I have to wait till 200 sec but my concern is I want to wait but whenever object is on screen I don't want keep me busy in WAITING MODE.
How will I write code in automation?
Thanks
Ok, this might give you idea how to follow-up:
For your view implement an accessibilityValue method which returns a JSON formatted value:
- (NSString *)accessibilityValue
{
return [NSString stringWithFormat:
#"{'MyButtonisVisible':%#}",
self.MyButton.isHidden ? #"false" : #"true"];
}
Then somehow you can access it from your test javascript:
var thisproperty = eval("(" + element.value() + ")");
if (thisproperty.MyButtonisVisible) {
UIATarget.localTarget().tap({"x":100, "y":100});
}
Hope that helps.
If you make the name different when you enable the button you can do this:
var awesomeButton = target.frontMostApp().mainWindow().buttons()[0];
UIATarget.localTarget().pushTimeout(200);
awesomeButton.withName("My Awesome Button");
if (awesomeButton.isVisible()) {
UIALogger.logError("Error no awesome button!");
}
UIATarget.localTarget().popTimeout();
withName will repeatedly test the name and control will return to your script once the name matches or when the time out is reached.
Per Apple's Doc
withName:
Tests if the name attribute of the element has the given string value. If the match fails, the test is retried until the current timeout expires.
Timeout Periods:
If the action completes during the timeout period, that line of code returns, and your script can proceed. If the action doesn’t complete during the timeout period, an exception is thrown.
https://developer.apple.com/library/etc/redirect/xcode/ios/e808aa/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/UsingtheAutomationInstrument/UsingtheAutomationInstrument.html#//apple_ref/doc/uid/TP40004652-CH20
Is the conversation.id not reset when conversation.end is called?
Scenario: I have an app that uses conversation scope in CRUD, so when I visit the list page it starts a conversation. Go to the detail and click back will call end conversation and begin conversation again. But while I'm at debug mode I found out that when conversation.end() is called conversation is set to null. Then when I reinvoke conversation.begin() conversation.id is not reset to 1 but rather the last value + 1. Is it correct to behave that way?
What's more puzzling is after logout and login again, the conversation.id pick up the last value + 1.
My environment: Jboss 7.1.3 using javaee-api.
protected void beginConversation() {
if (conversation.isTransient()) {
conversation.begin();
}
}
protected void endConversation() {
if (!conversation.isTransient()) {
conversation.end();
}
}
So basically I have a base entity (where the above code is defined.) extended by all the backing beans. When a list page is render it will call beginConversation. Clicking the back button in detail page will call endConversation.
Why should the conversation id be reset?
The best way to solve those questions is to directly having a look in the specification (in your case CDI 1.0), which states that the container has to generate an id for the conversation, but not how.
Check out this question, which states how it's done in WELD.
I have this problem : when i call the Content class (the one who decide which page to view, due to the #param) I do somethings like this :
History.addValueChangeHandler(this);
if(!History.getToken().isEmpty()){
changePage(History.getToken());
} else {
History.newItem("homepage");
}
So, now, if i look at browser's navigation bar, i see http://localhost:8084/GWT/?gwt.codesvr=127.0.0.1:9997#homepage. And that's right. Unfortunatly, If i press Back on my browser, i see that it load the previous address, such as http://localhost:8084/GWT/?gwt.codesvr=127.0.0.1:9997
I have a sort of "fake" page at the beginning.
1 - How can I fix it? And start the application with a default token, or remove it in the history. Or just call the onValueChange method when there is empty token, and after decide the workflow with a sort of switch/if-else.
2 - As related question, when i call History.addValueChangeHandler(this); in the costructor class, netbeans say "Leaking this in constructor". What it means?
Cheers
Maybe you forgot to add History.fireCurrentHistoryState(); to end of onModuleLoad() method?
You need to set a history token and fire the history change event with current token.
Heres how you could do it:
/ If the application starts with no history token, redirect to a new
// 'homepage' state.
String initToken = History.getToken();
if (initToken.length() == 0) {
History.newItem("homepage");
}
// Add widgets etc
// Add history listener
History.addHistoryListener(yourHistoryHandler);
// Fire the initial history state.
History.fireCurrentHistoryState();
IMHO, home url in form of "proto://hostname#homepage" is ugly :)
1. Just a suggestion:
String token = History.getToken();
String page = token.isEmpty() ? "homepage" : token;
changePage(page);
2. Does Your EntryPoint implement ValueChangeHandler<String>?