I am creating a sample application in angularjs 2.0. While developement I came across with a serious problem - I can't inject anything to the component through the constructor function.
This is the plnkr url : https://plnkr.co/edit/g1UcGmYPLtY8GiXuNHzK?p=preview
I used the following code for importing ItemService from app.item.service.ts
import { ItemService } from './app.item.service';
Then I specified provider as
#Component({
selector: 'list-todo',
template: `
<ul>
<li *ngFor="let item of items">{{item.text}}</li>
</ul>
`,
providers : [ItemService]
})
After that, given code for TodoComponent as
export class TodoComponent implements OnInit {
items:Array<Object> = [];
constructor(private itemService: ItemService){ //here is the problem
}
ngOnInit(){
this.getItems();
}
getItems(){
this.items = this.itemService.getItems();
}
}
When I try to inject ItemService through constructor , I am getting an error : " Error: Can't resolve all parameters for TodoComponent: (?)."
I am not able to inject even angularjs providers like Injector.
However, this method works for me :
const injector = ReflectiveInjector.resolveAndCreate([ItemService]);
this.itemService = injector.get(ItemService);
I am using the following versions of libraries for developement as mentioned in my package.json
"dependencies": {
"#angular/common": "2.0.0",
"#angular/compiler": "2.0.0",
"#angular/core": "2.0.0",
"#angular/forms": "2.0.0",
"#angular/http": "2.0.0",
"#angular/platform-browser": "2.0.0",
"#angular/platform-browser-dynamic": "2.0.0",
"#angular/router": "3.0.0",
"#angular/upgrade": "2.0.0",
"core-js": "^2.4.1",
"reflect-metadata": "^0.1.3",
"rxjs": "5.0.0-beta.12",
"systemjs": "0.19.27",
"zone.js": "^0.6.23",
"angular2-in-memory-web-api": "0.0.20",
"bootstrap": "^3.3.6"
},
"devDependencies": {
"concurrently": "^2.2.0",
"lite-server": "^2.2.2",
"typescript": "^2.0.2",
"typings":"^1.3.2"
}
Angular version: 2.0.0 final
Browser: all
attaching the error log I got from console :
(index):16 Error: Error: Can't resolve all parameters for TodoComponent: (?).
at CompileMetadataResolver.getDependenciesMetadata (http://localhost:3000/node_modules/#angular/compiler/bundles/compiler.umd.js:14404:21)
at CompileMetadataResolver.getTypeMetadata (http://localhost:3000/node_modules/#angular/compiler/bundles/compiler.umd.js:14301:28)
at CompileMetadataResolver.getDirectiveMetadata (http://localhost:3000/node_modules/#angular/compiler/bundles/compiler.umd.js:14074:30)
at eval (http://localhost:3000/node_modules/#angular/compiler/bundles/compiler.umd.js:14167:51)
at Array.forEach (native)
at CompileMetadataResolver.getNgModuleMetadata (http://localhost:3000/node_modules/#angular/compiler/bundles/compiler.umd.js:14161:51)
at RuntimeCompiler._compileComponents (http://localhost:3000/node_modules/#angular/compiler/bundles/compiler.umd.js:16803:49)
at RuntimeCompiler._compileModuleAndComponents (http://localhost:3000/node_modules/#angular/compiler/bundles/compiler.umd.js:16741:39)
at RuntimeCompiler.compileModuleAsync (http://localhost:3000/node_modules/#angular/compiler/bundles/compiler.umd.js:16732:23)
at PlatformRef_._bootstrapModuleWithZone (http://localhost:3000/node_modules/#angular/core/bundles/core.umd.js:6954:29)
Evaluating http://localhost:3000/dist/main.js
Error loading http://localhost:3000/dist/main.js(anonymous function) # (index):16ZoneDelegate.invoke # zone.js:203Zone.run # zone.js:96(anonymous function) # zone.js:462ZoneDelegate.invokeTask # zone.js:236Zone.runTask # zone.js:136drainMicroTaskQueue # zone.js:368ZoneTask.invoke # zone.js:308
I see that your tsconfig.json isn't correct.
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": false,
"emitDecoratorMetadata": true, <== it should be true
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false,
"outDir": "dist"
}
}
This is the magic sauce for DI. emitDecoratorMetadata: true. This option will preserve type information in your object's metadata.
See also
How does the TypeScript Angular DI magic work?
Injecting services in services in Angular 2
You code is fine!
Here is your updated plunker: https://plnkr.co/edit/6SR8Ibljuy0ElEBU87ox?p=preview
Did some changes to your system.js.config!
// ADDED THESE TWO OPTIONS BELOW
//use typescript for compilation
transpiler: 'typescript',
//typescript compiler options
typescriptOptions: {
emitDecoratorMetadata: true
},
and this..
app: {
main: './main.ts', // CHANGES HERE
defaultExtension: 'ts' // CHANGES HERE
},
Related
I am building a reusable react component without using react-app and I am very new to Jest. I keep on getting this message. I have tried several post solutions on Stackoverflow but I am stuck at the moment:
● Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
C:\Users\User\Documents\accessible-date-picker\src\__tests__\DatePicker.spec.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { DatePicker } from '../containers/DatePicker';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
I have the following configuration but I cannot figure out why I cannot resolve the problem:
//jest.config.js
module.exports = {
roots: ["<rootDir>/src"],
testMatch: [
"**/__tests__/**/*.+(ts|tsx|js)",
"**/?(*.)+(spec|test).+(ts|tsx|js)",
],
transform: {
"^.+\\.(ts|tsx)$": "ts-jest",
},
coveragePathIgnorePatterns: [
"/node_modules/"
],
moduleNameMapper: {
"\\.(css|less)$": "identity-obj-proxy",
}
};
Here is my tsconfigurations:
{
"compilerOptions": {
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"esModuleInterop": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
},
"include": [
"src"
]
}
Here are my dev dependencies:
"devDependencies": {
"#babel/core": "^7.12.7",
"#babel/plugin-transform-runtime": "^7.12.1",
"#babel/preset-env": "^7.12.7",
"#babel/preset-react": "^7.12.7",
"#babel/preset-typescript": "^7.12.7",
"#babel/runtime": "^7.12.5",
"#teamsupercell/typings-for-css-modules-loader": "^2.4.0",
"#types/fork-ts-checker-webpack-plugin": "^0.4.5",
"#types/jest": "^26.0.15",
"#types/react": "^17.0.0",
"#types/react-dom": "^17.0.0",
"#types/webpack": "^4.41.25",
"#types/webpack-dev-server": "^3.11.1",
"#typescript-eslint/eslint-plugin": "^4.8.1",
"#typescript-eslint/parser": "^4.8.1",
"babel-loader": "^8.2.1",
"css-loader": "^5.0.1",
"eslint": "^7.14.0",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.2.0",
"fork-ts-checker-webpack-plugin": "^6.0.3",
"jest": "^26.6.3",
"style-loader": "^2.0.0",
"ts-jest": "^26.4.4",
"ts-node": "^9.0.0",
"typescript": "^4.1.2",
"webpack": "^5.6.0",
"webpack-cli": "^4.2.0",
"webpack-dev-server": "^3.11.0"
}
}
Any help will be much appreaciated!
Looks like your test file is a js file (src\__tests__\DatePicker.spec.js) instead of ts?x file which means this pattern will never meet "^.+\\.(ts|tsx)$": "ts-jest".
However, you might know tsc can also have capability to transpile your js code as well as long as you set allowJs: true as you already did. So I think your problem would be fixed as you refine your pattern to to transform above including jsx file:
{
transform: {
"^.+\\.(t|j)sx?$": "ts-jest",
}
}
I have a test for a test for a TSX file written in a JSX file which fails to run due to unexpected token:
Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
I have another test written in JSX for a JSX file which does run. I am using React Testing Library but I don't think this is the issue as the test fails on the file imports.
Stack trace:
export { default as add } from './add.js';
^^^^^^
SyntaxError: Unexpected token export
1 | import React from 'react';
> 2 | import { debounce } from 'lodash-es';
| ^
3 |
4 | interface Props {
5 | bodyContent?: string
at ScriptTransformer._transformAndBuildScript (node_modules/#jest/transform/build/ScriptTransformer.js:537:17)
at ScriptTransformer.transform (node_modules/#jest/transform/build/ScriptTransformer.js:579:25)
at Object.<anonymous> (components/tsx/TestComponentTSX.tsx:2:1)`
Jest config:
module.exports = {
moduleDirectories: [
'node_modules'
],
transform: {
"\\.tsx?$": "ts-jest",
"\\.jsx?$": "babel-jest",
},
globals: {
"ts-jest": {
"tsConfig": '<rootDir>/tsconfig.json'
}
}
}
TS Config:
{
"compilerOptions": {
"outDir": "./dist/",
"noImplicitAny": true,
"module": "es6",
"target": "es5",
"jsx": "react",
"allowJs": true,
"allowSyntheticDefaultImports": true
}
}
TestComponentTSX.tsx
import React from 'react';
import { debounce } from 'lodash-es';
interface Props {
bodyContent?: string
}
function TestComponentTSX(props: Props) {
const clickHandler = (): void => {
console.log('I am being clicked!');
};
const debouncedClickHandler = debounce(clickHandler, 400)
return (
<div>
<h1>Hello World!</h1>
<p>{props.bodyContent || 'World...'}</p>
<button type="button" onClick={debouncedClickHandler}>Click me!</button>
</div>
)
}
export default TestComponentTSX;
TestComponentTSX.test.tsx
import React from 'react';
import { render } from '#testing-library/react';
import TestComponentTSX from './TestComponentTSX';
describe('The TSX component is testable', () => {
test('The component renders', () => {
// Arrange
const { getByText } = render(
<TestComponentTSX />
);
// Act
// Do something
// Assert
expect(getByText('Hello World!'));
})
});
package.json
{
"name": "jesttypescriptreact",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build-dev": "cross-env NODE_ENV=development webpack"
},
"author": "",
"license": "ISC",
"dependencies": {
"lodash-es": "^4.17.15",
"react": "^16.10.1",
"react-dom": "^16.10.1"
},
"devDependencies": {
"#babel/core": "^7.6.2",
"#babel/plugin-proposal-class-properties": "^7.5.5",
"#babel/plugin-proposal-object-rest-spread": "^7.6.2",
"#babel/preset-env": "^7.6.2",
"#babel/preset-react": "^7.0.0",
"#babel/preset-typescript": "^7.6.0",
"#testing-library/react": "^9.2.0",
"#types/jest": "^24.0.18",
"#types/lodash-es": "^4.17.3",
"#types/react-dom": "^16.9.1",
"babel-loader": "^8.0.6",
"cross-env": "^6.0.0",
"jest": "^24.9.0",
"ts-jest": "^24.1.0",
"ts-loader": "^6.2.0",
"typescript": "^3.6.3",
"webpack": "^4.41.0",
"webpack-cli": "^3.3.9"
}
}
After messing around with this for absolutely ages it looks like the problem was to do with the lodash-es package and Jest not supporting ES modules. This is mentioned here: https://github.com/facebook/jest/issues/4842
Using #CarlosCrespo answer as a basis I also had to tell babel not to ignore lodash-es when transpiling using the transformIgnorePatterns property to give me the following:
jest.config.js
module.exports = {
moduleDirectories: [
'node_modules'
],
transform: {
"\\.tsx?$": "ts-jest",
"\\.jsx?$": "babel-jest", // if you have jsx tests too
},
globals: {
"ts-jest": {
"tsConfig": '<rootDir>/tsconfig.json'
}
},
transformIgnorePatterns: [
"[/\\\\]node_modules[/\\\\](?!lodash-es/).+\\.js$"
],
}
In addition to this I also needed to update my tsconfig.json after another error - Cannot read property createElement of undefined was caused whilst using TypeScript: https://github.com/testing-library/react-testing-library/issues/374
tsconfig.json
{
"compilerOptions": {
"outDir": "./dist/",
"noImplicitAny": true,
"lib": ["dom", "esnext"],
"module": "esnext",
"target": "es5",
"jsx": "react",
"esModuleInterop": true,
"allowJs": true,
"allowSyntheticDefaultImports": true
},
"exclude": ["node_modules"]
}
Looks like you have to add this to your Jest config file
"transform": {
"\\.tsx?$": "ts-jest",
"\\.jsx?$": "babel-jest", // if you have jsx tests too
},
"globals": {
"ts-jest": {
"tsConfig": pathToYourTsConfigFile
}
}
more on that here: https://jestjs.io/docs/en/configuration.html#transform-object-string-pathtotransformer-pathtotransformer-object and here https://kulshekhar.github.io/ts-jest/user/config/
I've since discovered another alternative for the specific case of lodash-es. You can use the normal lodash library and just import the function you need. You can then get the benefit of the lodash-es package without needing to use transformIgnorePatterns.
E.g:
import camelCase from 'lodash/camelCase';
camelCase('my string');
I have used "MVC ASP.NET Core with Angular" template.
I am trying to include phantomJS and run the tests, but i get the following errors:
ERROR in [at-loader] ..\\node_modules\zone.js\dist\zone.js.d.ts:122:11 TS2451: Cannot redeclare block-scoped variable 'Zone'.
ERROR in [at-loader] ..\\node_modules\zone.js\ dist\zone.js.d.ts:363:14 TS2300: Duplicate identifier 'HasTaskState'.
ERROR in [at-loader] ..\\node_modules\zone.js\ dist\zone.js.d.ts:372:14 TS2300: Duplicate identifier 'TaskType'.
ERROR in [at-loader] ..\\node_modules\zone.js\ dist\zone.js.d.ts:458:15 TS2451: Cannot redeclare block-scoped variable 'Zone'.
PhantomJS 2.1.1 (Windows 7 0.0.0) ERROR ReferenceError: Can't find variable: Map at ../wwwroot/dist/vendor.js:12460
Below are the node module version i have been using(package.json):
"dependencies": {
"#angular/animations": "4.1.2",
"#angular/common": "4.1.2",
"#angular/compiler": "4.1.2",
"#angular/core": "4.1.2",
"#angular/forms": "4.1.2",
"#angular/http": "4.1.2",
"#angular/platform-browser": "4.1.2",
"#angular/platform-browser-dynamic": "4.1.2",
"#angular/platform-server": "4.1.2",
"#angular/router": "4.1.2",
"#types/node": "7.0.18",
"angular2-template-loader": "0.6.2",
"aspnet-prerendering": "^2.0.5",
"aspnet-webpack": "^1.0.29",
"awesome-typescript-loader": "3.1.3",
"bootstrap": "3.3.7",
"css": "2.2.1",
"css-loader": "0.28.1",
"es6-shim": "0.35.3",
"event-source-polyfill": "0.0.9",
"expose-loader": "0.7.3",
"extract-text-webpack-plugin": "2.1.0",
"file-loader": "0.11.1",
"html-loader": "0.4.5",
"isomorphic-fetch": "2.2.1",
"jquery": "3.2.1",
"json-loader": "0.5.4",
"preboot": "4.5.2",
"raw-loader": "0.5.1",
"reflect-metadata": "0.1.10",
"rxjs": "5.4.0",
"style-loader": "0.17.0",
"to-string-loader": "1.1.5",
"typescript": "2.3.2",
"url-loader": "0.5.8",
"webpack": "2.5.1",
"webpack-hot-middleware": "2.18.0",
"webpack-merge": "4.1.0",
"zone.js": "0.8.10"
},
"devDependencies": {
"#types/chai": "3.5.2",
"#types/jasmine": "2.5.47",
"chai": "3.5.0",
"istanbul-instrumenter-loader": "^3.0.0",
"jasmine-core": "2.6.1",
"karma": "1.7.0",
"karma-chai": "0.1.0",
"karma-chrome-launcher": "2.1.1",
"karma-cli": "1.0.1",
"karma-coverage-istanbul-reporter": "^1.3.0",
"karma-htmlfile-reporter": "^0.3.5",
"karma-jasmine": "1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"karma-phantomjs-launcher": "^1.0.4",
"karma-webpack": "2.0.3",
"phantomjs-prebuilt": "^2.1.15"
}`
and the tsconfig.json is as follows:
`{
"compilerOptions": {
"moduleResolution": "node",
"target": "es5",
"sourceMap": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"skipDefaultLibCheck": true,
"lib": [ "es6", "dom" ],
"types": [ "node" ]
},
"exclude": [
"bin",
"node_modules"
],
"atom": { "rewriteTsconfig": false }
}`
and the webpack.config.js code is :
`const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
module.exports = (env) => {
// Configuration in common to both client-side and server-side bundles
const isDevBuild = !(env && env.prod);
const sharedConfig = {
stats: { modules: false },
context: __dirname,
resolve: {
extensions: ['.js', '.ts'],
modules: [path.join(__dirname, "node_modules")]
},
output: {
filename: '[name].js',
publicPath: '/dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
},
module: {
rules: [
{ test: /\.ts$/, include: /ClientApp/, use: ['awesome-typescript-loader?silent=true', 'angular2-template-loader'] },
{ test: /\.html$/, use: 'html-loader?minimize=false' },
{ test: /\.css$/, use: [ 'to-string-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize' ] },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
]
},
plugins: [new CheckerPlugin()]
};
// Configuration for client-side bundle suitable for running in browsers
const clientBundleOutputDir = '..//wwwroot/dist';
const clientBundleConfig = merge(sharedConfig, {
entry: { 'main-client': '..//ClientApp/boot-client.ts' },
output: { path: path.join(__dirname, clientBundleOutputDir) },
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('..//wwwroot/dist/vendor-manifest.json')
})
].concat(isDevBuild ? [
// Plugins that apply in development builds only
new webpack.SourceMapDevToolPlugin({
filename: '[file].map', // Remove this line if you prefer inline source maps
moduleFilenameTemplate: path.relative(clientBundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
})
] : [
// Plugins that apply in production builds only
new webpack.optimize.UglifyJsPlugin()
])
});
return [clientBundleConfig];
};
`
How can i solve the errors mentioned above? I have tried solutions mentioned in https://github.com/monounity/karma-typescript/issues/83. Nothing worked.
Any help would be appreciated!
Looking forward for some answer.
Thanks.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~``
Solution to include chrome headless:
included "puppeteer" in package.json under dev dependencies.
Configured in Karma.config.js:
const ChromiumRevision = require('puppeteer/package.json').puppeteer.chromium_revision;
const Downloader = require('puppeteer/utils/ChromiumDownloader');
const revisionInfo = Downloader.revisionInfo(Downloader.currentPlatform(), ChromiumRevision);
module.exports = function (config) {
config.set({ ...
browsers: ['ChromeHeadless'],
..
});
};
phantomJS and run the tests, but i get the following errors:
PhantomJS is old and doesn't support ES6 features like Map. You can try to get it to work with core-js but you are essentially trying to lift a dead tech to modern standards.
More
The replacement for phantomjs is chrome headless.
I'm trying to upgrade a giant client-side app from Angular 1.x to Angular 2, and I've hit a really annoying roadblock. I've recreated the issue with a dummy, light-weight project (files pasted below), but let me just explain the problem first.
Basically, when my tsconfig.json specifies module as commonjs, I get the following error in my chrome dev console:
app.module.ts:1Uncaught ReferenceError: require is not defined
When I switch the module to system, I get the following error:
Uncaught TypeError: Invalid System.register call. Anonymous System.register calls can only be made by modules loaded by SystemJS.import and not via script tags.
And when I switch module to umd, everything works fine. But given that angular themselves suggest using commonjs, I'm concerned that umd is not the right answer. However, if I'm wrong about that and umd is perfectly fine, I'd love to hear a good explanation as to why.
Here's my code to reproduce my issue:
tsconfig.json:
{
"compilerOptions": {
"target": "es5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false
}
,
"exclude": [
"node_modules"
]
}
typings.json:
{
"globalDependencies": {
"angular": "registry:dt/angular#1.5.0+20160922195358",
"core-js": "registry:dt/core-js#0.0.0+20160725163759",
"jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
"jquery": "registry:dt/jquery#1.10.0+20160929162922",
"node": "registry:dt/node#6.0.0+20160909174046"
}
}
systemjs.config.js :
(function (global) {
System.config({
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
app: 'app',
// angular bundles
'#angular/core': 'npm:#angular/core/bundles/core.umd.js',
'#angular/common': 'npm:#angular/common/bundles/common.umd.js',
'#angular/compiler': 'npm:#angular/compiler/bundles/compiler.umd.js',
'#angular/platform-browser': 'npm:#angular/platform-browser/bundles/platform-browser.umd.js',
'#angular/platform-browser-dynamic': 'npm:#angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'#angular/ ': 'npm:#angular/http/bundles/http.umd.js',
'#angular/router': 'npm:#angular/router/bundles/router.umd.js',
'#angular/forms': 'npm:#angular/forms/bundles/forms.umd.js',
// other libraries
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api',
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
},
'angular-in-memory-web-api': {
main: './index.js',
defaultExtension: 'js'
}
}
});
})(this);
package.json :
{
"name": "mattsApp",
"version": "0.0.1",
"dependencies": {
"angular": "^1.5.8",
"#angular/common": "~2.0.2",
"#angular/compiler": "~2.0.2",
"#angular/core": "~2.0.2",
"#angular/forms": "~2.0.2",
"#angular/http": "~2.0.2",
"#angular/platform-browser": "~2.0.2",
"#angular/platform-browser-dynamic": "~2.0.2",
"#angular/router": "~3.0.2",
"#angular/upgrade": "~2.0.2",
"angular-in-memory-web-api": "~0.1.5",
"bootstrap": "^3.3.7",
"core-js": "^2.4.1",
"reflect-metadata": "^0.1.8",
"rxjs": "5.0.0-beta.12",
"systemjs": "0.19.39",
"zone.js": "^0.6.25"
},
"devDependencies": {
"concurrently": "^3.0.0",
"lite-server": "^2.2.2",
"typescript": "^2.0.3",
"typings":"^1.4.0"
},
"scripts": {
"start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
"lite": "lite-server",
"postinstall": "typings install",
"tsc": "tsc",
"tsc:w": "tsc -w",
"typings": "typings"
}
}
app.js :
angular.module('app', []);
app.module.ts :
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { upgradeAdapter } from './upgrade_adapter';
#NgModule({
imports: [ BrowserModule ]
})
export class AppModule { }
upgradeAdapter.bootstrap(document.body, ['app'], {strictDi: true});
appCtrl.ts :
angular.module('app')
.controller('appCtrl', ['$scope', function($scope) {
$scope.hello = "howdy worldy";
}]);
upgrade_adapter.ts :
import { UpgradeAdapter } from '#angular/upgrade';
import {AppModule} from "./app.module";
export const upgradeAdapter = new UpgradeAdapter(AppModule);
What am I missing?
you need instantiate the UpgradeAdapter with a non null parametter. In this way you need pass a forwardRef instance, something like this:
const upgradeAdapter = new UpgradeAdapter(forwardRef(() => AppModule));
finally you need import the forwardRef
import {NgModule, forwardRef} from '#angular/core';
First, thanks Andres. I need to read up a bit about the forwardRef to understand what that does. But it turns out that the answer in my particular case was something different.
I didn't post my index.html here (simple oversight), but the problem was that I wasn't loading my modules with the System.import('app'). Embarrassing error, I have to admit. So the answer is to add that line.
I should note that this led to a different error which I solved, but I'll point it out here in case others have a similar issue. Since this is a hybrid angular 1 and 2 app, I have typescript files that are sometimes used by angular 1 controllers / directives / etc, and also by angular 2 components. I had changed those typescript files to use export so I could import them into my angular 2 components. This led me to also change my /// in the angular 1 files to use import. Unfortunately, this gave me an "undefinedModule" error. The solution (in my case) is not to use export on typescript files unless they are ONLY used with the angular 2 components. Meaning, in some angular 2 components, I'm actually using the /// and not the import.
Just thought other people might find that useful.
I am using toPromise() and its working fine from the website but I get the following errors when I am in code view.
[
I suspect its something todo with my local modules.
The code for the components is
import "rxjs/Rx";
import './rxjs-extensions';
import { Injectable } from '#angular/core';
import { Headers, Http } from '#angular/http';
#Injectable()
export class TokenValidatorService {
constructor(private http: Http) { }
validateToken(token: string): Promise<string> {
return this.http.get('/api/downloader/' + token + '/valid')
.toPromise()
.then(response => {
return response.text()
})
.catch(this.handleError);
}
getDownloadUrl(token: string, pin: string): Promise<string> {
return this.http.get('/api/downloader/' + token + '/' + pin + '/getlink')
.toPromise()
.then(response => {
return response.text()
})
.catch(this.handleError);
}
private handleError(error: any): Promise<any> {
console.error('An error occurred', error); // for demo purposes only
return Promise.reject(error.message || error);
}
}
My package.json is
{
"version": "1.0.0",
"name": "asp.net",
"private": true,
"devDependencies": {
"gulp": "^3.9.1",
"gulp-clean": "^0.3.2"
},
"dependencies": {
"#angular/common": "2.0.0",
"#angular/compiler": "2.0.0",
"#angular/core": "2.0.0",
"#angular/forms": "2.0.0",
"#angular/http": "2.0.0",
"#angular/platform-browser": "2.0.0",
"#angular/platform-browser-dynamic": "2.0.0",
"#angular/router": "3.0.0",
"#angular/upgrade": "2.0.0",
"core-js": "^2.4.1",
"reflect-metadata": "^0.1.3",
"rxjs": "^5.0.0-beta.12",
"systemjs": "0.19.27",
"zone.js": "^0.6.23"
}
}
and my systemjs.config.js is
/**
* System configuration for Angular samples
* Adjust as necessary for your application needs.
*/
(function (global) {
System.config({
paths: {
// paths serve as alias
'npm:': 'https://unpkg.com/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
app: 'app',
// angular bundles
'#angular/core': 'npm:#angular/core/bundles/core.umd.min.js',
'#angular/common': 'npm:#angular/common/bundles/common.umd.min.js',
'#angular/compiler': 'npm:#angular/compiler/bundles/compiler.umd.min.js',
'#angular/platform-browser': 'npm:#angular/platform-browser/bundles/platform-browser.umd.min.js',
'#angular/platform-browser-dynamic': 'npm:#angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.min.js',
'#angular/http': 'npm:#angular/http/bundles/http.umd.min.js',
'#angular/router': 'npm:#angular/router/bundles/router.umd.min.js',
'#angular/forms': 'npm:#angular/forms/bundles/forms.umd.min.js',
// other libraries
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api',
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
},
'angular-in-memory-web-api': {
main: './index.js',
defaultExtension: 'js'
}
}
});
})(this);
You will notice that I load directly from unpkg I suspect that this is why it works in runtime. This is a VS Project it VS is taking care of the typescript etc, the tsconfig.json is
{
"compileOnSave": true,
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false
},
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
Edit
It's discussed in the following pages
https://github.com/ReactiveX/rxjs/issues/1696 and https://github.com/Microsoft/TypeScript/issues/8518
I have upgraded to TS2 and I still have the issue.