framework icon indicating copy to clipboard operation
framework copied to clipboard

Injected variables in app.js don't load on initial screen

Open LilSebastian5000 opened this issue 7 years ago • 3 comments

I'm submitting a bug report

  • Library Version:
    "aurelia-bootstrapper": "2.3.1",
    "aurelia-fetch-client": "1.7.0",
    "aurelia-framework": "1.3.0",
    "aurelia-history-browser": "1.2.0",
    "aurelia-loader-webpack": "2.2.1",
    "aurelia-logging-console": "1.0.0",
    "aurelia-pal-browser": "1.8.0",
    "aurelia-polyfills": "1.3.0",
    "aurelia-router": "1.6.3",
    "aurelia-templating": "1.10.1",
    "aurelia-templating-binding": "1.5.2",
    "aurelia-templating-resources": "1.7.1",
    "aurelia-templating-router": "1.3.3",

and

    "aurelia-loader-nodejs": "1.0.1",
    "aurelia-pal-nodejs": "1.2.0",
    "aurelia-protractor-plugin": "1.0.6",
    "aurelia-testing": "1.0.0",
    "aurelia-tools": "1.0.0",
    "aurelia-webpack-plugin": "2.0.0-rc.5",

Please tell us about your environment:

  • Operating System: Windows 10

  • Node Version: v8.9.0

  • NPM Version: 6.7.0
  • Aurelia CLI OR JSPM OR Webpack AND Version webpack 3.12.0

  • Browser: All

  • Language: ESNext

Current behavior: When injecting a variable into the constructor of app.js, it is not initialized on the first screen loaded in the application. When navigating to a subsequent screen, it becomes available for use in the

Expected/desired behavior: A variable initialized in the constructor of app.js should be available to all viewModels within

  • What is the motivation / use case for changing the behavior? This previously worked with aurelia-framework 1.1.5

Example Code based on skeleton-esnext-webpack, after updating dependencies in package.json

constants.js : export const TEST_CONST = "Constant!";

app.js:

import {PLATFORM} from 'aurelia-pal';
import * as Constants from './constants';
import {inject} from 'aurelia-framework';

@inject(Constants)
export class App {
  constructor(constants) {
    this.constants = constants;
  }

  configureRouter(config, router) {
    config.title = 'Aurelia';
    config.map([
      { route: ['', 'welcome'], name: 'welcome',      moduleId: PLATFORM.moduleName('./welcome'),      nav: true, title: 'Welcome' },
      { route: 'users',         name: 'users',        moduleId: PLATFORM.moduleName('./users'),        nav: true, title: 'Github Users' },
      { route: 'child-router',  name: 'child-router', moduleId: PLATFORM.moduleName('./child-router'), nav: true, title: 'Child Router' }
    ]);

    this.router = router;
  }
}

welcome.html:

<template>
  <section class="au-animate">
    <h2>${heading}</h2>
    <h2>CONSTANT: ${constants.TEST_CONST}</h2>
</template>

The above constant does not print in welcome.html. However, if I put it inside users.html, it does print on that screen.

LilSebastian5000 avatar Feb 08 '19 17:02 LilSebastian5000

@LilSebastian5000 The behavior described probably comes from implicit binding context inheritance of composition engine. Can you check if welcome.js view model has property name constants?

bigopon avatar Feb 08 '19 19:02 bigopon

@bigopon So, welcome.js does not have a property named constants and neither does users.js. However, users.html is still able to access the constants property despite its omission, while welcome.html cannot.

This can be reproduced in the skeleton-esnext-webpack repository after upgrading all existing aurelia dependencies to the latest, as well as webpack to version 3.12.0, and then adding the initialization of the constants as shown.

I reproduced it in there after discovering it in my own team's application after upgrading, making sure it wasn't anything odd that was specific to our project :). It's easy enough to fix by just initializing it in the constructor of the first screen of the application, but I don't know if that is expected behavior?

LilSebastian5000 avatar Feb 08 '19 22:02 LilSebastian5000

Inheriting binding context is desirable in some scenarios, such as composition with only view specified. There is no context being specified, so the newly compose view should use the parent binding context.

There is some other scenarios where it's less desirable to inherit binding context, such as composition with both view and view model specified. Inheriting binding context in this case seems like a source of surprising and buggy behavior.

This thread in templating resources https://github.com/aurelia/templating-resources/issues/222 is a good relevant discussion where you can get more information about this.

We will probably address this in a major of aurelia-templating-resources to reduce the surprising behavior.

bigopon avatar Feb 08 '19 22:02 bigopon