Using require breaks router...?

It works for me when bluebird is removed from aurelia.json prepend section. But that breaks IE11 if it is important for you. for me it is :frowning:

1 Like

@magnusdanielson If you dont need to use Bluebird’s promise cancellation feature, adding the following lines to your index html will make it work:

<script>Promise = undefined</script>
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js"></script> 

I think it boils down to the following difference:

Native

Bluebird

Notice how the 2 “micro task resolved” is logged after “promise then chain resolved” in bluebird, which could cause this line https://github.com/aurelia/router/blob/master/src/router.js#L204 to run before the micro task queue that bindings (read Repeat) uses to process changes / model / render UI


That said, it still doesn’t explain why it worked before, and now it stops working.

1 Like

The bug only affects end user when both issue(1) and issue(2) are present.

It worked before because issue(2) doesn’t exist before aurelia-templating-resources 1.7.0.

  • issue 2 is absent

It worked on gistrun because the rjs-bundle doesn’t bundle bluebird.

  • issue 1 is absent

This means the issue (1) (timing bug with bluebird) has been here for a long long time but didn’t manifest itself, like a recessive gene.

2 Likes

So cool to watch you two get to the root of it (-:

1 Like

@leo-mck in case you did not follow github issues. This bug has been fixed by @bigopon in latest aurelia release.

2 Likes

Do you have a release or specifics on what fixed this. I have been having issues in a value converter when I moved to the following:

aurelia-binding 2.1.1 -> 2.1.2
aurelia-router 1.6.1 -> 1.6.2
aurelia-templating 1.8.1 -> 1.8.2
aurelia-templating-resource 1.7.0 -> 1.7.1

One of those seems to have changed the order of the call to the value converter or when it is queued. With the latest version as of 2 days ago, the parameters into the value converter are undefined when I hit refresh (F5). They are available if I navigate to a page via the router. Something in the later version of these seems to have changed the order of execution somewhere.

Any advice? This is on a branch in my project that I set up about 3 months ago to move to webpack 4, but there is always something that is preventing me from merging it.

Thank you!

1 Like

That sounds like a regression in aurelia-binding. If you can confirm it, please create a github issue in the repo.

You can read the release notes on github.

1 Like

Thank you for the help. I reasonably sure that there is an issue in one of those four packages, but I will narrow it down and try to see exactly what change caused the problem.

1 Like

I tested by upgrading each package one at a time until it broke. Now I know the problem is in aurelia-templating 1.8.1 -> 1.8.2. Reverting that package fixes the error. Maybe the change to the composition-engine.js? I am out of time right now but will narrow it down further tonight.

1 Like

Can you share some code to reproduce it?

1 Like

I tried to do this more simply but I am not sure how to set versions with gist so I made a simple project. To keep it similar to my project I used a fork based on a dotnet core/webpack setup by @MaximBalaganskiy. You can download from git. Just run the following to see it work:

git clone -b aurelia-template-error https://github.com/elmt1/AureliaDotnetTemplate.git
npm install
dotnet build
dotnet run

You should see the text “home” on the page that is pulled in using a terminology value-converter. It should display “Home”.

To see it fail, delete the package-lock.json, node-modules directory and change the aurelia-templating to 1.8.2 in the package.json and run the commands above again. If you navigate away from the home page and come back it will work.

There are many ways to accomplish what this value converter is doing, so a work-around/better way might be the answer. However, the way I did this was simple and made sense to me. In my real applications a locale selection is defined in app.html and that feeds into the navigation and the rest of the application so defining and sharing the locale and terminology array in app.ts seemed OK.

1 Like

@elmt1 thanks for reporting. This is really bad.

The issue is not value converter. The issue is in your home.html, you use terminology which is defined in app.ts, not home.ts.

The usage works (I mean before aurelia-templating v1.8.2) because of one Aurelia feature called inheritBindingContext. That flag is by default set to true for any router loaded component. So your home component actually can access the variables defined in app module through overrideContext on binding scope.

The Aurelia team actually regretted on this default behaviour, but kept it anyway for not wanting to break backwards compatibility.

Now aurelia-templating v1.8.2 just broke it, not directly, but by worsening an existing router bug.
https://github.com/aurelia/router/issues/612

Solution

I don’t think you can wait for the router fix. I’m afraid the issue would not be fixed within few days.

As I stated above, the default inheritBindingContext behaviour is not recommended by Aurelia team, so it’s better to not rely on it.

You can retain the terminology object on your LocaleService itself, then inject LocalService to home.ts (or any component wants to access terminology).

In your home.html, you can access localService.terminology.
Or you can add a computed property in home.ts to keep existing home.html.

1 Like

Thank you for the in-depth description. Are you saying this is not likely to be fixed until there is a 2.x version? I am actually about 5 months waiting for stability on a WebPack4 branch so a few weeks would be OK.

Originally, I was injecting the LocaleService into home.ts and was in the process of adding it to ~50 other components when I found it wasn’t necessary and I could reference variables in the containing component and refactored. Being lazy, I was very happy when I stumbled on this behavior.

I looked for documentation on inheritBindingContext. It seems to be fairly obscure. It is not mentioned in any of 5 books I have on Aurelia and what I found by searching seemed to imply the default is false and I see an instance of BehaviorInstruction defaults to false but a static reference defaults to true.

1 Like

Not that late I guess.

It is not documented at all. There are 3 cases.

  1. default to false, for normal component creation <child-component></child-component>
  2. default to true, for router loaded view, through <router-view></router-view>. This one is now broken due to the wrong lifecycle callback sequence.
  3. default to true, for dynamically composed view, by <compose></compose>.

It’s very obscure, to optionally turn it on for normal component:

import {processContent} from 'aurelia-framework';
@processContent((compiler, resources, node, instruction) => {
  instruction.inheritBindingContext = true;
  return true;
})
export class ChildComponent {/*...*/}
1 Like

@huochunpeng, it has been a long time and I was starting to have issues with dependencies so I went ahead and used your suggestion to inject a singleton of the localeService. That worked, but added several hundred lines of code to my application because I was relying on this in a lot of places :slightly_smiling_face: I was adding to the message that it might be helpful in vNext to have the to declare a variable in a component as global.

While typing that, it occurred to me, why not just inject the singleton into the value converter? A quick test and it seems to work. I can now back out those several hundred lines of code but I am very happy because I end up with a cleaner implementation. Now I autoinject the the singleton onto the value converter containing the language translations and using it is simpler because I don’t have to pass anything but the value to translate. Big win for me.

4 Likes