ag-grid-vue: Is there an event which is guaranteed to fire before onGridReady and onFirstDataRendered? - ag-grid

I've just started using ag-grid with vue, and noticed that sometimes onGridReady fires first, and sometimes onFirstDataRendered fires first. I was wondering if there was an event guaranteed to fire before both of those, so that I could set this.gridApi = grid.api once. (I'm currently setting it at the beginning of both as a workaround).
Update: this only seems to happen when the vue component containing the grid is initialized after page load (via a v:if), and not when it is visible on page load.

Actually you missed something I suppose, cuz onFirstDataRendered couldn't be executed before gridReady - cuz only after initialization (exact grid-ready event) - the grid itself would be ready to proceed.
Here is a hierarchy from ag-grid doc, which sais :
GridReadyEvent - will be executed very first.

Related

Why would fireEvent work but userEvent not work?

In short, I have a table row with an onclick event. I am getting this via
const row = screen.getByRole('row', { name: /My row/i })
await userEvent.click(row)
This does not trigger the event handler. However, if I do:
const row = screen.getByRole('row', { name: /My row/i })
fireEvent.click(row)
This works fine.
I know userEvent uses more events to simulate a row click, but the event handler works fine in the live application too. Are there any reasons why userEvent might not work?
Like most very strange things, the problem lied elsewhere. But for documentation purposes, this was due to the app rerendering while doing my assertions. What would happen was this:
App renders, making a bunch of API calls
My API call for my test finishes, say, get user
findByText('My User') passes and gets me my DOM element
Another API call finishes, re-rendering the component to show this data
The result of findByText is no longer the current active DOM element
click fires
As its no longer in the document, there's nothing to click/fire an event
I changed my previous lines to check for ALL data loads before grabbing my row and it seems to consistently be working. This means I have to assert things unrelated to my tests, but that may be due to my app having poor UX with things popping in as they load?
Either way, I'm not 100% confident this is the reason, but if
userEvent.click is not firing events, or
toBeInTheDocument is failing, even if findBy worked
It may be due to your app rerendering after you've asserted everything has loaded. Hope I can save someone else 3 days of suffering like I had to to find that simple fact...

Creating a plugin mechanism: What is the earliest event fired by AgGrid?

I would like to create a plugin mechanism for my custom wrapper around AgGrid. Currently I am doing so with an interface like this:
export interface IGridPlugin {
onGridReady: (e: GridReadyEvent) => void;
}
Then, in my wrapper around AgGrid, I add an onGridReady event handler that goes through the supplied list of plugins and invokes their onGridReady method one at a time. They can then perform any initialization that they require - like adding event handlers via e.api.addEventListener
gridOptions.onGridReady = (e: GridReadyEvent) => {
plugins?.forEach(plugin => plugin.onGridReady(e));
}
Unfortunately, the onGridReady event appears to only fire after the grid initially loads and renders. One of the plugins I've created will restore the grid state from url params when onGridReady fires, and will subsequently keep the url params updated as the grid state changes.
Since onGridReady fires after the initial rendering, there's a small delay where the grid is displayed without the application of the preserved grid state in the url. I was hoping to find an earlier event that might make more sense for this.
Alternatively, I suppose I could allow the plugins to modify the gridOptions directly before the grid is even constructed... but using events feels a little safer - preventing one plugin from setting itself up as the sole event handler for something that other plugins may want to use and accidentally disable some/all of the functionality of other plugins.
Is there a better event or alternative mechanism for adding such plugins to AgGrid? I would like to make sure that the plugins have access to the api and columnApi instances in any approach taken.

Where can I found documentation about page lifecycle events?

I am using cdp (https://github.com/mafredri/cdp) in order to use devtools protocol to generate a pdf of a page. But first I need to know when the page is completely loaded. I found that the networkIdle event can help me to know when this occurs. But, I have troubles because the networkIdle event sometimes fired twice. Then I need to know when this one is fired
There are two parts for what you're looking for.
First of all, the reason the event is fired twice. When a new tab (target) is created, the first page it loads is about:blank. You get lifecycle events for this page as well. The second time the load event is fired is the one you're looking for (if you're using Page.lifecycleEvent).
Now, to handle the second matter - there are also other events you can use. The basic one for page loading is Page.loadEventFired, which, as far as I recall, will only be fired for the actual page (but I could be wrong about this one).
Important note: If you're using lifecycle events, they are fired for each frame separately, meaning that the main frame might finish loading before the sub frames are loaded. Page.loadEventFired has a different behavior and waits for all frames to fire their load event.
Here is a good article on the page lifecycle api.
Another possible solution could be:
document.onreadystatechange = function () {
if (document.readyState === 'complete') {
run the screenshot code...
}
}

Using a button click event, destroy the ag-grid

Using plain old javascript version of ag-grid.
I would like to destroy the ag-grid that is in a div from a button click event.
How do i destroy the grid?
There is a method named destroy().
As per documentation:
destroy()
Gets the grid to destroy and release resources. If you are using Angular (version 1 or 2) you do not need to call this, as the grid links in with the AngularJS 1.x lifecycle. However if you are using Web Components or native Javascript, you do need to call this, to avoid a memory leak in your application.
Have a look at the Plunk - Destroy grid I created.
gridOptions.api.destroy();
As you can see, by calling this function, the grid gets destroyed.
As described in the documentation, it not only clears the DOM, but also takes care of memory leaks.

When does converse.js chatBoxInitialized event actually emit?

I'm trying to configure a few settings in a converse.js chatbox (title, removing avatar, chatbox width) PRIOR to it "rendering" and displaying the chatbox.
While not explicitly saying so, I had figured that the "chatBoxInitialized" event would fire AFTER the chatbox object was created, but prior to rendering and displaying.
What I'm finding is that when my handler function for that event is called, the chatbox is already displayed, so clearly my understanding of "chatboxinitialized" is incomplete. Inside the handler, I have used available methods in chatbox object such as
chatbox.setChatBoxWidth(350);
chatbox.model.attributes.fullname = data;
to set chatbox attributes but while the statements execute and have a momentary effect, as soon as the handler function completes, something is setting those values back, and the box "re-renders" and displays as it was before my function ran.
Is there a more appropriate event to register for so these values can be set prior to chatbox rendering? Are there more appropriate "chatbox set functions" that can be used to properly set such things as size, and turn off avatars, rather than just reaching into DOM directly and manipulating after the fact?
Any help would be appreciated.
If you look at the code, you'll see that chatBoxInitialized gets triggered after the chatbox's HTML has already been rendered.
See here: https://github.com/jcbrand/converse.js/blob/393bbe020e45ccd2abe10683117a8f854dea9145/src/converse-chatview.js#L281
Looking at the code, I don't see any event that's triggered after the chatbox has been created, but before it's rendered.
However, in the current master branch of converse.js (to be released soon), you can set the fullname after the chatbox has been created, and it will then appear properly.
You're however setting it wrong. With Backbone.js you must use get and set and not the attributes property.
So this:
chatbox.model.attributes.fullname = data;
must be changed to this:
chatbox.model.set({'fullname': data});
Concerning setting the chatbox width, I think the best way to do that is to set the relevant Sass variable, see here:
https://github.com/jcbrand/converse.js/blob/393bbe020e45ccd2abe10683117a8f854dea9145/sass/converse/_variables.scss#L111
Then run make css to generate new CSS.