(Flutter) setState of First Page from Second Page - dart

I have a ListView Builder in the first Page, which receives content(items) from the Second Page. When I hit submit button in Second Page, I use:
Navigator.of(context).pop
Which takes me back to First Screen.
The problem is that it is not updating the item created in the list unless i restart the app.
I have tried:
1) Calling an instance of First Page and using:
firstPageinstance.setState((){});
2) I have also tried to call a function from the First Page class, which invokes setState:
firstPageinstance.funtionWhichCallsetStateinFirstageClass();
But none of this works. The list is updated only when I Restart the App.
P.S. The list items are saved and called from an SQLite database. Also, Let me know if you need more details.

When navigating to your SecondPage await the result like this:
bool isUpdated = await Navigator.push(context, MaterialPageRoute(builder: (context) => SecondPage()),)
if(isUpdated) // do your list update logic here
When going back to FirstPage(tap on submit button), send the expected value such as:
Navigator.pop(context, true);
Helpful read: https://flutter.dev/docs/cookbook/navigation/returning-data

Related

Testing-library unable to find rc-menu

I'm trying to implement integration tests on our React frontend which uses Ant design. Whenever we create a table, we add an action column in which we have a Menu and Menu Items to perform certain actions.
However, I seem unable to find the correct button in the menu item when using react-testing-library. The menu Ant design uses is rc-menu and I believe it renders outside of the rendered component.
Reading the testing-library documentation, I've tried using baseElement and queryByRole to get the correct DOM element, but it doesn't find anything.
Here's an example of what I'm trying to do. It's all async since the table has to wait on certain data before it gets filled in, just an FYI.
Tried it on codesandbox
const row = await screen.findByRole('row', {
name: /test/i
})
const menu = await within(row).findByRole('menu')
fireEvent.mouseDown(menu)
expect(queryByRole('button', { name: /delete/i })).toBeDisabled()
the menu being opened with the delete action as menu item
I had a same issue testing antd + rc-menu component. Looks like the issue is related to delayed popup rendering. Here is an example how I solved it:
jest.useFakeTimers();
const { queryByTestId, getByText } = renderMyComponent();
const nav = await waitFor(() => getByText("My Menu item text"));
act(() => {
fireEvent.mouseEnter(nav);
jest.runAllTimers(); // ! <- this was a trick !
});
jest.useRealTimers();
expect(queryByTestId("submenu-item-test-id")).toBeTruthy();

How to attach a new BrowserWindowOpener to a button, without destroying the button first?

on Vaadin 7 I have the working code :
private void gridAttachmentsClickItemEventAction(ItemClickEvent event) {
// blablabla some code to get the data from the repository
byte[] data = bibocoAttachmentResponseEntity.getBody().getContent();
StreamResource.StreamSource source = convertByteArrayToStreamResource(data);
String filename = "c:\\droppdf\\"
+"temp"+bibocoAttachmentResponseEntity.getBody().getFileName()+LocalDate.now().toString();
StreamResource resource = new StreamResource(source, filename);
resource.setMIMEType("application/pdf");
resource.getStream().setParameter("Content-Disposition", "attachment; filename=" + filename);
BrowserWindowOpener opener = new BrowserWindowOpener(resource);
opener.extend(btnAttachmentPreview);
}
When I click on a grid row, the data is collected from that grid
and code following on it gets the data byte[] from a repository by calling a service.
Afterwards, when the user clicks on btnAttachmentPreview a new browser tab opens
and shows the pdf (that's what's in the data byte[])
This works fine the first time, but when I select a new row in the grid,
the problem is that the second call does not set the listener to the button right.
It show the first data byte[] again in a new tab, not the current data ...
The method is accessed, the correct data[] has been loaded in the array the second time, I checked.
I believe the listener on the btnAttachmentPreview attached due the code
opener.extend(btnAttachmentPreview);
should be binned (empty'ed or nulled) first. But I have no reference to it as for as I can tell.
Problem is that I don't want to destroy the btnAttachmentPreview object.
(The btnAttachmentPreview is a global variable and is set to a layout that I may not change. I know, not nice, but it's a ancient product)
When I close the browser and restart and clicking another row, the right data byte[] is showed.
Anyone a clue ?
Any help appreciated
You can remove an extension using its remove() method, i.e. opener.remove();.
If you cannot easily structure your code to store a reference to the old opener so that you have it available when you want to add a new one, then you can use btnAttachmentPreview.getExtensions() to get a collection of all current extensions and then from that you can find the appropriate extension (if any) and call remove() on it.

Flutter Patterns with Widgets

I 've a search form with multiple fields and it's result (a json from an http call) should be listed in a ListView.
Which is the correct pattern in Flutter to show that results? Update the state of the ListView (making it visible) and hide the search form? Or wait for the results in the search form page (search_page.dart) and then send those results to other page (results_page.dart) where the ListView will show it?
Thanks!
You can use the Navigator class to navigate to a new widget:
onPressed: () {
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new SecondScreen()),
);
}
You can pass arguments into the constructor there. There's a little more info about this here:
https://flutter.io/cookbook/navigation/navigation-basics/

JQuery mobile - click event only fires on current page

I have the following:
$(document).on("pageinit", function (event) {
alert("pageinit called");
$('#logout').bind('click', function() {alert("clicked!");});
});
The first time the page runs you get a single alert 'pageinit called'. Clicking the element with id #logout fires the alert 'clicked!'. If I click any other links in this page I still get the 'pageinit called' alert (and I get it multiple times, apparently for each page I have previously navigated as well) but subsequently the handler for #logout is gone and never never re-established.
Can anyone tell me how I can get the handler for #logout to remain? I've tried:
$('#logout').die('click').live('click', function() {alert("clicked!");});
to no avail.
After looking more closely (and as commented by Omar), this problem is caused by a combination of the jquery mobile paging system AND trying to attach to a 'single' element by id.
In my case each time I clicked a link within the page it would load into the jqm paging system a separate page, each one containing its own #logout element. My solution was to query for all the buttons and attach handlers to each one:
var buttons = $("*[id='logout']");
buttons.each(function() {
// handle click or whatever here
});
Instead of:
var button = $('#logout'); // Only hooks into the first #logout element

WatiN: Print Dialog

I have a screen that pops up on load with a print dialog using javascript.
I've just started using WatiN to test my application. This screen is the last step of the test.
What happens is sometimes WatiN closes IE before the dialog appears, sometimes it doesn't and the window hangs around. I have ie.Close() in the test TearDown but it still gets left open if the print dialog is showing.
What I'm trying to avoid is having the orphaned IE window. I want it to close all the time.
I looked up DialogHandlers and wrote this:
var printDialogHandler = new PrintDialogHandler(PrintDialogHandler.ButtonsEnum.Cancel);
ie.DialogWatcher.Add(printDialogHandler);
And placed it before the button click that links to the page, but nothing changed.
The examples I saw had code that would do something like:
someDialogHandler.WaitUntilExists() // I might have this function name wrong...
But PrintDialogHandler has no much member.
I initially wasn't trying to test that this dialog comes up (just that the page loads and checking some values on the page) but I guess it would be more complete to wait and test for the existence of the print dialog.
Not exactly sure about your situation, but we had a problem with a popup window that also displayed a print dialog box when loaded. Our main problem was that we forgot to create a new IE instance and attach it to the popup. Here is the working code:
btnCoverSheetPrint.Click(); //Clicking this button will open a new window and a print dialog
IE iePopup = IE.AttachToIE(Find.ByUrl(new Regex(".+_CoverPage.aspx"))); //Match url ending in "_CoverPage.aspx"
WatiN.Core.DialogHandlers.PrintDialogHandler pdhPopup = new WatiN.Core.DialogHandlers.PrintDialogHandler(WatiN.Core.DialogHandlers.PrintDialogHandler.ButtonsEnum.Cancel);
using (new WatiN.Core.DialogHandlers.UseDialogOnce(iePopup.DialogWatcher, pdhPopup)) //This will use the DialogHandler once and then remove it from the DialogWatcher
{
//At this point the popup window will be open, and the print dialog will be canceled
//Use the iePopup object to manage the new window in here.
}
iePopup.Close(); // Close the popup once we are done.
This worked for me:
private void Print_N_Email(Browser ie)
{
//Print and handle dialog.
ie.Div(Find.ById("ContentMenuLeft")).Link(Find.ByText(new Regex("Print.*"))).Click();//orig
Browser ie2 = Browser.AttachTo(typeof(IE), Find.ByUrl(new Regex(".*Print.*")));
System.Threading.Thread.Sleep(1000);
PrintDialogHandler pdh = new PrintDialogHandler(PrintDialogHandler.ButtonsEnum.Cancel);
new UseDialogOnce(ie2.DialogWatcher, pdh);
ie2.Close();
}
You still might want to check your browser AutoClose property ie.AutoClose

Resources