aadams
June 16, 2017, 2:03pm
20
What if you have multip template options per route?
Using your example:
FlowRouter.route('/page/:_id', {
name: 'page',
action() {
import('../../ui/pages/Page/Page.js').then(() => {
BlazeLayout.render('layout', { main: 'Page', SideBars: 'Sidebar' });
});
},
});
How would you dynamically import both Page and Sidebar in this case?
I use Promise.all([]).then()
2 Likes
aadams
June 16, 2017, 2:37pm
22
Promise.all? Sorry, I’m not familiar with Promise syntax, will you help with a code snippet @rmuratov ?
FlowRouter.route('/page/:_id', {
name: 'page',
action() {
Promise.all([
import('../../ui/pages/Page/Page.js',
import('../../ui/pages/Sidebar/Sidebar.js'
]).then(() => {
BlazeLayout.render('layout', { main: 'Page', SideBars: 'Sidebar' });
});
},
});
3 Likes
aadams
June 16, 2017, 2:58pm
24
Thanks @robfallows !
Just curious, why isn’t the original example wrapped in a promise? Is the import statement a wrapper on a promise?
FlowRouter.route('/page/:_id', {
name: 'page',
action() {
import('../../ui/pages/Page/Page.js').then(() => {
BlazeLayout.render('layout', { main: 'Page', SideBars: 'Sidebar' });
});
},
});
Yes - it returns a Promise.
You could also use async/await
:
FlowRouter.route('/page/:_id', {
name: 'page',
async action() {
await import('../../ui/pages/Page/Page.js');
await import('../../ui/pages/Sidebar/Sidebar.js');
BlazeLayout.render('layout', { main: 'Page', SideBars: 'Sidebar' });
},
});
Although that could be slower, since it waits each time, whereas Promise.all
runs them concurrently.
5 Likes
aadams
June 16, 2017, 3:01pm
26
Very good. Thank you @robfallows !
1 Like
Or:
FlowRouter.route('/page/:_id', {
name: 'page',
async action() {
await Promise.all([
import('../../ui/pages/Page/Page.js'),
import('../../ui/pages/Sidebar/Sidebar.js')
]);
BlazeLayout.render('layout', { main: 'Page', SideBars: 'Sidebar' });
},
});
source: http://2ality.com/2017/01/import-operator.html#async-functions-and-import
3 Likes
That’s a good solution if you don’t care about order of evaluation - so in this case, if Sidebar.js
does not depend on Page.js
, then Promise.all
will evaluate faster because Promises in the array of Promises will be started concurrently.
However, they are not guaranteed to finish in the same order they were requested and in order to avoid complicating my answer I chose to use the form which is guaranteed to evaluate in order.
Some Promise packages have a Promise.waterfall
method for this use case.
Ideally, one can conceive of a complex Promise construct which is able to intermix concurrent with waterfall evaluations to achieve speed and order of resolution where necessary.
2 Likes
I’m having issues trying to do that with Meteor 1.7.
If i only use “import” the error says: “import statements must be
at top-level scope”
if i use import(’…/path/to/my/file’) the error says: “unexpected (”
Have you added your own babel config which is conflicting with Meteor’s configuration?
Make sure you’re using import
keyword with parenthesis (round brackets) like: import(/path/to/my/file')
This error very specific to the different import
- ES replacement for require
, and it is used with no parenthesis.
Tip: It’s always better to speak code, - share piece of the code where you’re having this exception, and 10-20 lines before/after that line.
1 Like
I haven’t, but i’m using coffeescript@2 on the project and having a .coffee file instead of regular .js
yes that’s what i’m doing.
will post a code snippet later, good idea.
mb coffee compiles code into the different result, or import
keyword is used by coffeescript itself.
try to write this part purely in JS.
I am using Meteor 1.8.2 with dynamic import and it fails when I attempt to connect to the running pages via network.
Reproduction
Meteor create --full test
This create a meteor project and can be accessed via network with route.js file as below
import { FlowRouter } from 'meteor/kadira:flow-router';
import { BlazeLayout } from 'meteor/kadira:blaze-layout';
// Import needed templates
import '../../ui/layouts/body/body.js';
import '../../ui/pages/home/home.js';
import '../../ui/pages/not-found/not-found.js';
// Set up all routes in the app
FlowRouter.route('/', {
name: 'App.home',
action() {
BlazeLayout.render('App_body', { main: 'App_home' });
},
});
FlowRouter.notFound = {
action() {
BlazeLayout.render('App_body', { main: 'App_notFound' });
},
};
// At this point the pages are accessible via network (my.local.ip:3000 ) without any errors
Then edit the route file by introducing dynamic imports, using original FlowRouter
FlowRouter.route('/', {
name: 'App.home',
action() {
import('../../ui/pages/home/home.js').then(() => {
BlazeLayout.render('App_body', { main: 'App_home'})
})
},
});
or FlowRouter Extra
FlowRouter.route('/', {
name: 'App.home',
waitOn() {
return import('/imports/ui/pages/home/home.js');
},
action() {
this.render('App_body', { main: 'App_home'});
}
});
both of them fail when you try to connect to this page via network
ie my.local.ip:3000 fails.
@dr.dimitru
Anyone with a solution please help. Regards;
jamgold
January 29, 2019, 10:27pm
37
Have you tried this?
FlowRouter.route('/', {
name: 'App.home',
action(params, queryParams, data) {
require('../../ui/pages/home/home.js');
BlazeLayout.render('App_body', { main: 'App_home'});
},
});
1 Like
Have you set your root url correctly it’s odd that it uses a different ip address.
This seems to work. Thank you!!!
Hello everyone, sorry for the late reply. See my answer here