How do I access the Ember global 'App' variable in an Ember CLI application?
Asked Answered
A

5

14

I am creating an Ember application using the Ember CLI. I have a view which invokes a component that I created. I am trying to access the global App variable to create my component and insert it into my layout.

The error: Uncaught ReferenceError: App is not defined

How do I fix this?

app.js

import Ember from 'ember';
import Resolver from 'ember/resolver';
import loadInitializers from 'ember/load-initializers';

Ember.MODEL_FACTORY_INJECTIONS = true;

var App = Ember.Application.extend({
  modulePrefix: 'client-web', // TODO: loaded via config
  Resolver: Resolver
});

loadInitializers(App, 'client-web');

export default App;

item-table.js (This is a view)

import Ember from 'ember';

export default Ember.View.extend({
    templateName: 'item-table',

    didInsertElement: function() {
        // All my other code here

        App.FreestyleChartComponent.create().appendTo($('#wp-chart td')); // This throws an error.
    }
});

app/components/freestyle-chart.js

import Ember from 'ember';

export default Ember.Component.extend({
    templateName: 'components/freestyle-chart',

    didInsertElement: function() {
        console.log('Inserted the component.');
    }
});
Aleksandropol answered 17/9, 2014 at 0:35 Comment(1)
I've removed my answer since it didn't help. Sorry mate.Byrann
I
5

I can think of two ways. The first is to put the App in the global scope manually.

var App = window.App = Ember.Application.extend();

The second is to import the App into your view:

import App from './path/to/app/file';

The latter is only possible if Ember CLI supports circular references. The official ES6 spec supports them but many transpilers don't (mine doesn't).

However, I don't think this is your root concern. For the most part, you shouldn't be accessing global variables in Ember CLI. Instead of placing the FreestyleChartComponent in the App namespace, why not just put it in a module and import it like any other module? Global variables are unavoidable (I experienced that today), but you should try to minimize them.

Interruption answered 17/9, 2014 at 0:40 Comment(4)
I tried the first option, didn't work. The second one compiled but now the error is "Uncaught TypeError: Cannot read property 'create' of undefined". How do I create a module? Couldn't find much information on that. Sorry about the newbie questions. Also, how would you dynamically create a component in an Ember CLI application assuming I didn't even ask the question here? Is my current script correct?Aleksandropol
If the first option didn't work, then you've done something else wrong. A specific error could help us track that problem down. As for the second one not working, it sounds like App.FreestyleChartComponent doesn't exist. I can't really help you diagnose that without more code.Interruption
I'm essentially following: emberjs.jsbin.com/axUNIJE/1/edit. Don't have anything different other than the fact that my app is created using the Ember CLI.Aleksandropol
Can you show us the code where you declare FreestyleChartComponent?Interruption
J
3

I do agree that you should not be accessing your app via the global namespace, however ember-cli actually does actually make you app a global with the name of your app being the name of the variable.

If you open /app/index.html in your ember-cli project you should see a script tag towards the bottom that looks like...

<script>
  window.YourAppName = require('your-app-name/app')['default'].create(YourAppNameENV.APP);
</script>

in the above example YourAppName would be your app available as a global

Jag answered 17/9, 2014 at 16:43 Comment(0)
F
2

Import the component that you want:

import FreestyleChartComponent from 'app_name/app/components/freestyle-chart';
Frannie answered 17/9, 2014 at 1:54 Comment(2)
I tried this and it can now find the component. Thanks! However, the error now says "Assertion failed: You cannot append to an existing Ember.View. Consider using Ember.ContainerView instead". I just changed the view to ContainerView and it now says "Uncaught Error: Assertion Failed: You tried to append to ([object Object]) but that isn't in the DOM". The template of the view also isn't on the page.Aleksandropol
You should ask that in another question, not in a comment here. That's unrelated to the original issue.Interruption
U
1

There is no straight forward way to do this since Ember CLI wants you to use the public API and its given components rather than accessing the App instance directly.

Most solutions consist of making the App instance global, whereby this one does not. I did not test this, but I think this should work:

appname/utils/application.js

export default {
   instance: null
};

appname/instance-initializers/application.js

import application from 'appname/utils/application';

export default {
  name: 'app-initializer',
  initialize: function (application) {
     application.instance = application;
  }
};

Now

import application from 'appname/utils/application';

and use application.instance in any file where you need the application instance.

Unpeople answered 10/9, 2015 at 19:6 Comment(0)
C
0

Justed tested with Ember 3.7.

import App from 'app-name/app';

app-name has to be replace with the name of your app (I guess the one in package.json).

Cryptonym answered 2/3, 2019 at 22:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.