Bind in blazor is delayed by 1 step - binding

I'm sorry because my english is pretty bad.
I have a problem and would love to get some help.
I'm trying to get return value from component and update it in another component.
When component B's product selection button is pressed, the selected product will be bound to the main screen, then an item will be updated again in component A.
The weird thing is that the first time I select, nothing happens. The second time I select the product, the first item is added to component A.
Even in component A itself, when I increase or decrease the number of products, the data in component A itself gets the same error.
Here is my source code
Component A
Component B
Main Screen

In index.razor you have two async void methods. Make them async Task and await them in C#.
async void runs unobserved, there is no UI update when they finish. You should never need async void in Blazor. Blazor supports async Task for eventhandlers.

Related

Angular Dart Router: navigating to the same component does not create a new instance even if canReuse() returns false

I'm using dart 2.0.0
With dart 1.24.3 and related angular router, I had a component with CanReuse() always returning false. In this case, when I navigated again to the same component, a new instance was created.
On the first call, onActivate() was called, and, when called the second time, the CanReuse() was executed and finally the onActivate() method on a new instance was called.
Now, with the last version, when we navigate a second time to the same component, CanReuse() and onActivate() are not called, and the same instance of the component is used.
Is there any way to change this behavior?
Edit 1:
Consider like you have a menu and each menu item navigate to a component. If you press the same menu item the same component is called. In my case the component called can manage data from different servers, so I can have multiple dataset active (but only one shown, almost like a tab..) at the same time. I have a list of open datasets, where the ones "not showed" are listed and you can select them again. There is a mechanism that preserve data and reinitialize the newly created instance from the selected one.
Theoretically I could manage everything in one instance only, but, as the logic is quite complicated, I would like to avoid it, and, in any case, I'd need to know when the menu item component (new or initialized from an existing dataset) has been selected (with an onActivate() call, for example..).
At present this only works if I select different components, let's say, for example, component A, component B, and then again component A.
If I call component A and then again component A, the onActivate() method is not called and I'm not able to know when a different dataset is needed.

Nested data and BLoCs in Flutter

My Flutter app has the following general structure:
The initial screen shows a list of contact objects. The user can tap a contact, which brings up
a detail screen that lets the user see the whole contact info, and modify any details temporarily. The user can either
dismiss the screen without saving the changes, or
tap a save button, which updates the contact permanently, and upon completion leads back to the initial screen.
I'm using FireStore. The list is built with Stream<QuerySnapshots>, and when the user taps an item, the app's router parses the route name (e.g. /contacts/123), creates the respective DocumentReference and forwards it to the detail screen's initializer, which then uses DocumentReference.get to load the details, and DocumentReference.updateData to save changes. Works beautifully – but is only a proof of concept.
Now I would like to hide FireStore and the remaining business logic behind a BLoC. This leads to some questions:
Keeping business logic out of the UI, as far as I understand it, implies that I should stick to named routes, and have the detail screen somehow use the route details to retrieve the relevant contact data through the BLoC. Is that true, and what's the best solution for this?
How can I subscribe to nested data using the BLoC? I want the detail screen to observe data changes, so that I can warn the user if the data becomes stale. Using functions on BLoCs (something like streamOfContact(contact) -> Stream<Contact>) is forbidden, so how would I do that with Sinks? Or is there generally a different way to do this without breaking the BLoC pattern? I'm very new to all of this, so may very well be I'm overlooking something important.
Similar question: How would I update a particular contact?
The tutorials I've found online only deal with root data (e.g. adding cart items to a cart, handling user authentication, ...), but I haven't seen an example showcasing nested data yet. Any help is highly appreciated!
1) Routing and navigation is in the responsibility of the UI layer. That means the UI layer must call Navigator.push[Named](...).
If it makes sense, you can move the logic that decides if the app should navigate to the detail screen:
// in the BLoC:
Stream<int> showContactDetail;
// in the UI layer:
bloc.showContactDetail.listen(_showContactDetail);
How you transfer the parameters to the detail route is totally up to you. You can use named routes, but it would be easier to transfer data with a builder:
void _showContactDetail(int contactId) {
Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) {
return ContactDetailPage(
contactId: contactId,
);
}));
}
2) One BLoC should be tied to a single screen, that means there should be a separate BLoC for the detail screen (or dialog/sidebar/...), and you would pass the id of your contact to the second BLoC as a constructor parameter, or using a StreamSink, or using a simple setter method.
I would recommend you to use plain old methods instead of StreamSinks for the BLoC inputs. Here is a recent discussion about the topic.
3) The question is not only how to update your contact from the detail screen, but also how the detail BLoC obtains the contact data (if you are only transferring the contact id).
The answer: Another application layer, what I would call the data layer, that is shared between all BLoCs. You can store the data in Firebase, a sqlite database or a simple Map<int, Contact>.
The data layer would also propagate changes to the backend, and notify all BLoCs when the data has changed, probably using a Stream.
The next question that would come up is where you put this data layer (e.g. a class called ContactService):
You can create the ContactService in your ContactListPage, then pass it to the ContactDetailPage in a constructor parameter (using a route builder, as explained above). No magic here. A side effect that you may not want is that the service will be discarded when the list page is popped.
InheritedWidget that is above the MaterialApp, or at least above the Navigator generated by the MaterialApp (You can use the builder of MaterialApp to wrap the navigator with your own widgets). Putting it that high up in the tree ensures that all pages of your app can access it.
Using scoped_model, which is basically the same. Must also be inserted above the navigator to be accessible from both routes
A static variable/singleton

Selenium Webdriver - Refresh Stale Element Shortcut?

I'm writing a Selenium test for my Rails application, and sometimes run into the "Stale Element" exception. It's easy enough to perform another lookup on the element before operating on it, but to keep my code DRY, I'm wondering - is there any sort of method available on Selenium::WebDriver::Element objects to "refresh" stale references?
EDIT: To clarify, I'm asking if there's some shorthand method for doing another find_by_xpath (or id, etc.) call with the same parameter being passed. It's perfectly functional, just not as terse as some sort of "refresh" method would probably be.
If I understand correctly, you are asking about some sort of "refresh" or "update" method on a WebElement instance.
Unfortunately, there is no such thing in selenium by definition. According to the relevant issue WebElement refresh() or getBy() needed:
WebElement object is a proxy, a representative of a DOM element. When
DOM element is destroyed by the browser, WebElement is marked "stale"
and can't be used anymore.
If you have a similar DOM element on another page, you can obtain it
with findElement, and Selenium will create a new WebElement object
(a proxy) for this new DOM element. Your old WebElement object will
remain stale because underlaying DOM object is destroyed and never can
be restored. Similarity is not equality.
I would recommend store element-specific locators, but once the page refreshes, you would still need to "refind" the element by the locator.
The only thing available is keeping track of your application state when writing your Selenium code.
Did you perform an action that refreshed the DOM? Then you need to perform another findElement call to get a new instance of the element you want to interact with next.
Otherwise, write your own method findElementByXpath in a Utility class that tries to find an element, catches a StaleElement exception and retries.
I am going to describe my case which is similar:
I tried to find a table cell with some value by doing this:
Get all table rows
For each row - get a collection of the columns
For each column - seek the value
One day, I had a case with too many results in the table. So, I programmed the loop to click the "Get next page" link/icon.
Simple? no! when the program clicked the "next page of the table" link, the WebElement which pointed to the table was not usable, I received the same error as the author of this question: StaleElementReferenceException
What I did is:
Get the XPATH of the table first, and then I changed the loop so if all the rows were scanned, and he value was not found and if the next icon is enabled:
Click the next page of the table.
Update the WebElement to re-point the table.
I hope I am clear.

Detect if JQuery Mobile came from a select dialog

I have a jquery mobile app that has a page. This page has three DIVs, I programmatically choose one of these DIVs based on a variety of variables. Regardless, the one DIV contains a select element. This element has 20 items in it. Because of the shear quantity, the select box opens in its own dialog. I'm fine with that, however, after a user makes a choice, the pagebeforeshow event of my hosting page is fired again. My problem is, I can't seem to figure out how to detect that this event was fired as a result of the user choosing an option or closing the select dialog.
Is there a way to detect in the pagebeforeshow event how we got here?
jQuery mobile passes meta-data to the callback functions of most events. From the docs on pagebeforehow:
Triggered on the "toPage" we are transitioning to, before the actual transition animation is kicked off. Callbacks for this event will recieve a data object as their 2nd arg. This data object has the following properties on it:
prevPage (object) - A jQuery collection object that contains the page DOM element that we are transitioning away from. Note that this collection is empty when the first page is transitioned in during application startup.
You should be able to use this in your callback function to branch to your advantage, i.e. detect if prevPage is the current page. This might look like:
$('#yourPage').live('pagebeforeshow', function(event, data) {
var from = data.prevPage;
// do some inspection of `from` and branch accordingly
// might require some experimental console.logging first
});
I also didn't verify the question raised in above comment, but data.prevPage has a copy of the entire previous page's HTML, accessed via data.prevPage[0].innerHTML. I'm sure you could do something like binding to the click event on the select dialog and tell it to add a class or whatever to the DOM where the user selected whatever entry, and scrape that back out of the HTML? Just throwing an idea out there.

bring the last loaded controls back when i restart the machine

I am working in video application in my application am using many controls for user friendly first i will Load the base from only after that i ll load the other controls based on user need.... here my need is if user load ten controls in this case if he shutdown the machine means when he restart the machine i need to bring the all controls back what he was load the controls before he shutdown. thanks in advance
is there is any possible to achive this without store the current control set, and positions etc..
You need to look at something like
Form and Control Position and Size
Utility
Save and restore Form position and
layout with this component
Basically what it boils down to, is that you need a way to store the current control set, and positions (possibly values too) to some sort of storage (XML file, Registry, Database) when the user exits your form/application.
Then once they reopen the form/application, you need to retrieve these settings for the given user (if any is available) and restore the form/application to that state.
How about making extension methods to Control class?
(Actually, appropriate .NET abstract base class, a sub-class of Control class, depending on UI. Do you use Windows Forms or XAML or ASP.NET?)
Something like:
public static class MyPositionExtensions{
public static void SaveState(this Control c){ /* Save position to xml-file */ }
public static void RestoreState(this Control c){ /* Load from xml-file */ }
}
Then in your closing just loop like
foreach(var c in MyControls)c.SaveState();
and opening like
foreach(var c in MyControls)c.RestoreState();

Resources