Right, looks like you're right about the menuItem
var not being available until some magic happens. A consistent way around this would be to check that v.menuItems
is a length greater than 0 in the rerender
method, so something like
rerender: function(component, helper) {
var menuItems = component.get('v.menuItems');
if (menuItems.length > 0) {
//you're good to go with external JS DOM shenanigans
}
this.superRerender();
}
At this point it's reasonable to assume that:
- External JS dependencies have been fully loaded
- menuItems is populated
- The navigation menu is 'ready' on the DOM
The 'dirty' part is where you have to call back to your external JS from Lightning- so you'll probably have to bind a function to the window.
Not to deviate too much from the original question- but this is the best way to work with external JS that requires the DOM to be 'ready'- have Lightning call a function on the window.
--- Edit for visibility ---
As mentioned in my comment below, I've tested the exact case on a Community, and confirmed that rerender
is RELIABLY called when menuItems is populated from within a Community context, when implemented following the instructions.
Anyway:
rerender
is called after menuItems
is populated. There is no disputing this fact. This meets your use case of needing to reliably interact with the DOM when it's "ready".
In the initial part of your question, I noted that you had a variable in the Extension
component that was local to it- and you were expecting a rerender
to be called once GetHelloWorld
initialises.
Unless you link the variable using the same parameter syntax as you do for the Composition
component- it will remain LOCAL to the component. It doesn't get touched by ANY of your other components. It's not going to rerender
.
--- Second edit ---
Well, looks like I got owned by Lightning, very very frightening again.
So- ignore everything I wrote above- here's what's happening:
rerender
isn't called by default- I think the reason it was calling it on my org is due to the CSS classes being loaded via ltng:require
.
v.menuItems
isn't reliably populated even if rerender
is called (I refreshed the page 2-3 times prior to writing the first edit, and walked off triumphant)
- The
valueChange
event is useless because there's no render
type event to signal that the menu is in the DOM
- Lightning is horrible
Apologies if I got the wrong end of the stick earlier- it looks like you're plum out of luck if you're looking for a clean solution to manipulate the navigation menu post render. Suggest maybe using click event or CSS to achieve said effects?
If you go via apex, the heap limitations will apply.
The workaround is to do a callout from javascript. Yes you can do that.
By default, you can’t make calls to third-party APIs from client-side
code. Add a remote site as a CSP Trusted Site to allow client-side
component code to load assets from and make API requests to that
site’s domain.
So if you do a callout from browser, its heap and cpu of device involved and should be alright.
That being said, the thing you have to worry about is, if its an authenticated call, then make sure you dont do a callout from browser passing username and password. Instead do a callout from apex to get access_token and then use that access_token to call 3rd party,
Src: https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_api_calls_platform.htm
Not able to call Composite REST request from LWC
Best Answer
After working with Salesforce on this I got interim workaround until continuations are supported by Lightning framework.
Create a Visualforce page what will be performing callouts using continuations and collecting responses on the page via backend rendered JS vars. Use Window.postMessage() to communicate and exchange data between lightning component and iframe.