Async routes with parameters fails. Why?

I was inspired by this question. I’m using async option in my routes.js like this :

path: '/article/:id',
async: function (routeTo, routeFrom, resolve, reject) {
  var router   = this;
  var app      = router.app;
  app.preloader.show();
  let id = routeTo.params.id;
  app.request.post('https://example.com/app/article/' + id, function (res) {
    app.preloader.hide();
    resolve(
    {
      componentUrl: './pages/article.html',
    },
    {
      context: {
        data: res
      }
    });
  });
}

I get this error :

framework7.bundle.min.js:13 Uncaught (in promise) TypeError: Cannot read property ‘2’ of null

Framework7 5.7.0
What is wrong ?

It has to do with the scope of your variable ‘app’. Because you use let id = ... it is only available in the same scope. Your callback function uses a regular function definition, which changes the context. If you use a arrow function, it keeps the scope where it is defined.

So I think it works if you change your callback function definition:

app.request.post('https://example.com/app/article/' + id, function (res) {
to
app.request.post('https://example.com/app/article/' + id, (res) => {

1 Like

Thank @Tim for your answer.
Indeed, let isn’t appropriate here.

The solution, I just found is to use templateUrl instead of componentUrl.

URL vs ComponentURL vs TemplateURL

That could be a second problem as well indeed :slight_smile: Probably you have a component file with only markup, which works in a template file. But in a component file that should be wrapped in <template> tags:

<template>
<div>My variable: {{data.var}}</div>
</template>
1 Like

@Tim, many thanks, you helped me a lot !
Finally to make it works (for future readers).

routes.js

path: '/article/:id',
async: function (routeTo, routeFrom, resolve, reject) {
  var router   = this;
  var app      = router.app;
  app.preloader.show();
  var id = routeTo.params.id;
  app.request.post('https://example.com/app/article/' + id, (res) => {
    app.preloader.hide();
    resolve(
      {
        componentUrl: 'pages/article.html',
      },
      {
        context: {
          data: JSON.parse(res)
        }
      }
    );
  });
}

pages/article.html

<template>
  <div>My variable: {{data.var}}</div>
</template>
1 Like

Great, you’re welcome! But shouldn’t your example state componentUrl instead of templateUrl right now? :wink:

1 Like

@Tim. Exact :flushed:
I’ve modified my answer above. I’ve tested, it works (only if I have <template></template> markup)
But I don’t understand why …