this is my Component
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'homeView',
templateUrl: '/home/home'
})
export class HomeViewComponent implements OnInit {
ngOnInit(): void {}
}
I am using AngularJS 2 with TypeScript 1.8.5 and trying to create component that will load template from Controller Action.
I am getting this error
main.bundle.js:667 Uncaught Error: Cannot find module ".//home/home"
I also tried it with home/home, the error is almost the same
main.bundle.js:667 Uncaught Error: Cannot find module "./home/home"
Error is not compile time error however - it pops up in browser console when page and the component is being loaded
So as you can see i dont want to load static template like home.template.html - that is working correctly. I want to load an HTML template from asp.net MVC Controller Action. I am not even hitting the debug point in the HomeController Home action.
Is there any way to make this work ? Seems like Angular keeps inserting this './' sign. Is there a way to configure this ? I ve read several tutorials on angular2 + mvc and it seems that this should be possible, but for some reason its not working for me.
My app.routes.ts
import {Routes} from "#angular/router";
import {MainViewComponent} from "../views/main-view/main-view.component";
import {MinorViewComponent} from "../views/minor-view/minor-view.component";
import {HomeViewComponent} from "../views/home-view/home-view.component";
export const ROUTES:Routes = [
// Main redirect
{ path: '', redirectTo: 'mainView', pathMatch: 'full'},
// App views
{path: 'mainView', component: MainViewComponent},
{path: 'minorView', component: MinorViewComponent},
{path: 'homeView', component: HomeViewComponent}
// Handle all other routes
//{path: '**', component: MainViewComponent }
];
app.module.ts
#NgModule({
declarations: [AppComponent],
imports : [
// Angular modules
BrowserModule,
HttpModule,
// Views
MainViewModule,
MinorViewModule,
// Modules
NavigationModule,
FooterModule,
TopnavbarModule,
RouterModule.forRoot(Approutes.ROUTES)
],
providers : [{provide: LocationStrategy, useClass: HashLocationStrategy}],
bootstrap : [AppComponent]
})
export class AppModule {}
EDIT : Some more info :
packages.json
{
"name": "inspinia_angular2_starter",
"version": "1.0.0",
"description": "Inspinia Admin Theme",
"repository": "https://wrapbootstrap.com/theme/inspinia-responsive-admin-theme-WB0R5L90S",
"scripts": {
"typings-install": "typings install",
"postinstall": "npm run typings-install",
"build": "webpack --inline --colors --progress --display-error-details --display-cached",
"server": "webpack-dev-server --inline --colors --progress --display-error-details --display-cached --port 3000 --content-base src",
"start": "npm run server"
},
"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",
"angular2-in-memory-web-api": "0.0.20",
"animate.css": "3.1.1",
"bootstrap": "^3.3.7",
"core-js": "^2.4.1",
"font-awesome": "^4.6.1",
"ie-shim": "^0.1.0",
"jquery": "^3.1.0",
"metismenu": "^2.5.0",
"pace": "0.0.4",
"pace-progress": "^1.0.2",
"reflect-metadata": "^0.1.3",
"rxjs": "5.0.0-beta.12",
"systemjs": "0.19.27",
"typings": "^1.3.2",
"zone.js": "^0.6.23"
},
"devDependencies": {
"angular2-template-loader": "^0.4.0",
"awesome-typescript-loader": "^1.1.1",
"bootstrap-webpack": "0.0.5",
"css-loader": "^0.23.1",
"exports-loader": "^0.6.3",
"expose-loader": "^0.7.1",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.9.0",
"imports-loader": "^0.6.5",
"raw-loader": "^0.5.1",
"style-loader": "^0.13.1",
"to-string-loader": "^1.1.4",
"typescript": "~1.8.5",
"url-loader": "^0.5.7",
"webpack": "^1.12.9",
"webpack-dev-server": "^1.14.0",
"webpack-merge": "^0.8.4"
}
}
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"outDir": "dist",
"rootDir": ".",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"moduleResolution": "node"
},
"exclude": [
"node_modules",
"bower_components"
],
"awesomeTypescriptLoaderOptions": {
"useWebpackText": true
},
"compileOnSave": false,
"buildOnSave": false,
"atom": {
"rewriteTsconfig": false
}
}
App is built using webpack
main.browser.ts
import {platformBrowserDynamic} from "#angular/platform-browser-dynamic";
import {AppModule} from "../src/app/app.module";
/*
* Bootstrap Angular app with a top level NgModule
*/
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
So, after what seemed like an eternity I finally got the the bottom of this.
The problem was in webpack using angular2-template-loader.
This module is responsible for inlining html template. In other words, it will do a require (using your templateUrl) behind the scenes on the template tag of your component. This, of course, breaks the functionality if you are using actual URLs as templateUrl and not PATHs, therefore the template is not there.
Based on what i read, it seems like the authors wont support this in the future. (If template is not found -> try to load it from URL)
More info here - https://github.com/angular/angular-cli/issues/1605
So, basically I just removed this component from config file :
webpack.config.js
BEFORE
module: {
loaders: [
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader', 'angular2-template-loader']
},
{
test: /\.css$/,
loader:
AFTER
module: {
loaders: [
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader']
},
{
test: /\.css$/,
loader:
Related
I'm new in TS & angular. Now I have a legacy playwright project, which I'd like to use ngx-logger for logging.
According to many ngx-logger tutorials, I know there might be 3 steps to integrate:
install ngx-logger
npm install --save ngx-logger
import the library in the root module, i.e., app.module.ts
import { LoggerModule, NgxLoggerLevel } from 'ngx-logger';
import LoggerModule.forRoot in your application module. This is where we can configure the logger:
#NgModule({
imports: [
BrowserModule,
HttpClientModule,
LoggerModule.forRoot({
serverLoggingUrl: 'http://localhost:4201/', // Replace with YOUR API
level: NgxLoggerLevel.TRACE,
serverLogLevel: NgxLoggerLevel.ERROR,
disableConsoleLogging: false
})
],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
So finally, we can start logging anywhere in the application:
export class AppComponent {
constructor(private logger: NGXLogger) {
this.logger.debug("Debug message");
this.logger.info("Info message");
this.logger.log("Default log message");
this.logger.warn("Warning message");
this.logger.error("Error message");
}
}
However, I'm stuck in step 2&3, because I don't know where to setup these in a playwright project.
In my playwright project, I only have config files like:
~/playwright.config.ts
~/src/config/launch.config.ts
~/src/config/testrunner.config.ts
none of them contains #NgModule I could inject the codes.
Can anyone give me some hints with how to proceed?
Thank in advance.
package.json
{
"name": "portal-test",
"version": "0.0.0",
"private": true,
"description": "Portal Test Automation Suite",
"homepage": "./",
"dependencies": {
"dotenv": "^16.0.0",
"eml-parser": "^1.0.6",
"expect-playwright": "^0.7.1",
"moment": "^2.29.4",
"ngx-logger": "^5.0.11",
"npm": "^7.19.1",
"path": "^0.12.7",
"pdf.js-extract": "^0.1.5",
"pdfreader": "^1.2.11",
"playwright-core": "^1.15.2",
"request-promise": "^4.2.6",
"ts-node": "^10.3.0",
"typescript": "^4.4.3",
"yarn": "^1.22.10"
},
"scripts": {
"compile": "npx tsc --incremental -p tsconfig.json",
"test": "CI_TEST_ENV=uat npx playwright test --config=src/config/testrunner.config.ts --headed",
"test-local": "CI_TEST_ENV=local npx playwright test --config=src/config/testrunner.config.ts --headed",
"test-local-headless": "CI_TEST_ENV=local npx playwright test --config=src/config/testrunner.config.ts",
"test-dev": "CI_TEST_ENV=dev npx playwright test --config=src/config/testrunner.config.ts --headed",
"test-uat": "CI_TEST_ENV=uat npx playwright test --config=src/config/testrunner.config.ts --headed"
},
"devDependencies": {
"#playwright/test": "^1.28.1",
"playwright": "^1.15.2"
},
"extends": []
}
I'm trying to use scss in my rails application, configured by webpacker. Whenever I run rails webpacker:compile, I get the following error:
ERROR in ./app/javascript/stylesheets/application.scss
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: expected "{".
╷
1 │ import api from "!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js";
│ ^
╵
app/javascript/stylesheets/application.scss 1:95 root stylesheet
I'm having trouble debugging this problem and would appreciate any help.
Dependencies
rails: 6.1
webpacker: 6.0.0.pre1
#webpack-cli/serve
webpack: 5.11
webpack-cli: 4.2
webpack-dev-server: 3.11
package.json
{
"name": "ostor",
"private": true,
"dependencies": {
"#popperjs/core": "^2.6.0",
"#rails/actioncable": "^6.1.2-1",
"#rails/activestorage": "^6.1.2-1",
"#rails/ujs": "^6.1.2-1",
"#rails/webpacker": "^6.0.0-beta.5",
"autoprefixer": "^10.2.4",
"bootstrap": "^v5.0.0-beta2",
"css-loader": "^5.0.2",
"css-minimizer-webpack-plugin": "^1.2.0",
"d3": "^6.2.0",
"jquery": "^3.5.1",
"mini-css-extract-plugin": "^1.3.7",
"postcss": "^8.2.6",
"postcss-loader": "^5.0.0",
"sass": "^1.32.7",
"sass-loader": "^11.0.1",
"style-loader": "^2.0.0",
"turbolinks": "^5.2.0",
"webpack": "^5.11.0",
"webpack-cli": "^4.2.0"
},
"version": "0.1.0",
"devDependencies": {
"#webpack-cli/serve": "^1.3.0",
"webpack-dev-server": "^3.11.2"
},
"babel": {
"presets": [
"./node_modules/#rails/webpacker/package/babel/preset.js"
]
},
"browserslist": [
"defaults"
]
}
config/webpack/base.js:
const { webpackConfig, merge } = require('#rails/webpacker')
const customConfig = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
exclude: /node_modules/,
use: [
// Creates `style` nodes from JS strings
"style-loader",
// Translates CSS into CommonJS
"css-loader",
// Compiles Sass to CSS
"sass-loader",
],
},
],
},
}
module.exports = merge(webpackConfig, customConfig)
app/javascript/packs/application.js
import ActiveStorage from "#rails/activestorage";
import * as RailsUjs from "#rails/ujs";
import Turbolinks from "turbolinks";
ActiveStorage.start();
RailsUjs.start();
Turbolinks.start();
import "channels";
import "bootstrap";
import "../stylesheets/application.scss";
Remove the custom config rules you added for SASS/SCSS. Webpacker 6 will provide the appropriate CSS rules for you when it detects you've installed css-loader, postcss-loader, mini-css-extract-plugin, etc.
For the shakapacker users:
You don't need to add the option:
test: /\.s[ac]ss$/i
in the "rules" section. You just need to add:
yarn add sass sass-loader
and:
extensions:
- .sass
- .scss
in your webpacker.yml file, and shakapacker will transpile sass/scss files.
I have an ASP.NET MVC project which uses ASP.NET WebAPI along with Angular for UI components. I'm fairly new to Angular so please bear with me. Below are the config files inside my project.
package.json file
{
"name": "angular-quickstart",
"version": "1.0.0",
"description": "QuickStart package.json from the documentation, supplemented with testing support",
"scripts": {
"build": "tsc -p src/",
"build:watch": "tsc -p src/ -w",
"build:e2e": "tsc -p e2e/",
"serve": "lite-server -c=bs-config.json",
"serve:e2e": "lite-server -c=bs-config.e2e.json",
"prestart": "npm run build",
"start": "concurrently \"npm run build:watch\" \"npm run serve\"",
"pree2e": "npm run build:e2e",
"e2e": "concurrently \"npm run serve:e2e\" \"npm run protractor\" --kill-others --success first",
"preprotractor": "webdriver-manager update",
"protractor": "protractor protractor.config.js",
"pretest": "npm run build",
"test": "concurrently \"npm run build:watch\" \"karma start karma.conf.js\"",
"pretest:once": "npm run build",
"test:once": "karma start karma.conf.js --single-run",
"lint": "tslint ./src/**/*.ts -t verbose"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"#angular/common": "~4.3.4",
"#angular/compiler": "~4.3.4",
"#angular/core": "~4.3.4",
"#angular/forms": "~4.3.4",
"#angular/http": "~4.3.4",
"#angular/platform-browser": "~4.3.4",
"#angular/platform-browser-dynamic": "~4.3.4",
"#angular/router": "~4.3.4",
"angular-in-memory-web-api": "~0.3.0",
"systemjs": "0.19.40",
"core-js": "^2.4.1",
"rxjs": "5.0.1",
"zone.js": "^0.8.4"
},
"devDependencies": {
"concurrently": "^3.2.0",
"lite-server": "^2.2.2",
"typescript": "~2.1.0",
"canonical-path": "0.0.2",
"tslint": "^3.15.1",
"lodash": "^4.16.4",
"jasmine-core": "~2.4.1",
"karma": "^1.3.0",
"karma-chrome-launcher": "^2.0.0",
"karma-cli": "^1.0.1",
"karma-jasmine": "^1.0.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~4.0.14",
"rimraf": "^2.5.4",
"#types/node": "^6.0.46",
"#types/jasmine": "2.5.36"
},
"repository": {}
}
systemjs.config.js file
/**
* System configuration for Angular samples
* Adjust as necessary for your application needs.
*/
(function (global) {
System.config({
//baseURL: '/',
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/http': '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/bundles/in-memory-web-api.umd.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
//meta: {
// './*.js': {
// loader: 'systemjs-angular-loader.js'
// }
//},
},
rxjs: {
defaultExtension: 'js'
}
}
});
})(this);
main.ts file
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { enableProdMode } from '#angular/core';
import { AppModule } from './app.module';
// Enable production mode unless running locally
//if (!/localhost/.test(document.location.host)) {
// enableProdMode();
//}
platformBrowserDynamic().bootstrapModule(AppModule);
app.routing.ts file
import { ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { HomeComponent } from './Components/home.component';
const appRoutes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent }
];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
app.module.ts file
import { NgModule } from '#angular/core';
import { APP_BASE_HREF } from '#angular/common';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { AppComponent } from './app.component';
import { routing } from './app.routing';
import { HomeComponent } from './Components/home.component';
import { ChangeService } from './Services/changes.service';
#NgModule({
imports: [BrowserModule, FormsModule, ReactiveFormsModule, HttpModule, routing],
declarations: [AppComponent, HomeComponent],
providers: [{ provide: APP_BASE_HREF, useValue: '/' }, ChangeService],
bootstrap: [AppComponent]
})
export class AppModule {}
changes.service.ts file
import { Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from '#angular/http';
#Injectable()
export class ChangeService {
constructor(private _http: Http) { }
get(url: string) {
return this._http.get(url);
}
}
app.component.ts file
import { Component, ElementRef, OnInit } from '#angular/core';
import { ChangeService } from './Services/changes.service';
#Component({
selector: 'moc-landing',
templateUrl: './app/Components/home.component.html',
styleUrls: ['./app/Components/home.component.css']
})
export class AppComponent implements OnInit {
maintitle: string;
statusList: IStatus[];
showByList: IShowBy[];
msg: string;
constructor(private elementRef: ElementRef, private _changeService: ChangeService) {
this.maintitle = this.elementRef.nativeElement.getAttribute('maintitle');
}
ngOnInit() {
this.LoadStatus();
this.LoadShowBy();
}
LoadStatus(): void {
this._changeService.get('http://localhost:56534/api/MoC/GetStatuses').subscribe(response => { this.statusList = response.json(); });
}
LoadShowBy(): void {
this._changeService.get('http://localhost:56534/api/MoC/GetShows').subscribe(response => { this.showByList = response.json(); });
}
}
Also in my WebApiConfig.cs, inside static Register method, I also update routeTemplate as below.
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
My issue is that, when I run the application from Visual Studio 2017 on http://localhost:5653; I get Failed to load resource: the server responded with a status of 400 (Bad Request)
When I looked at the browser's console, this is what I got,
I test the http request directly in my browser's address bar http://localhost:56534/api/MoC/GetStatuses, and it gives me the json data that I need. So, there's no problem in WebAPI side.
I found this SO post and, tried to follow Praveen M answer but it didn't worked for me.
Why did I get (400) bad request?, Did I miss an important configuration in my app.routing.ts?
Please, anyone here with a kind heart can spare me a coin?
Try changing:
providers: [{ provide: APP_BASE_HREF, useValue: '/' }, ChangeService]
to just:
providers: [ChangeService]
Well, after banging my head on the wall. I found the culprit of the issue. It's a stupid mistake of mine. The issue isn't on the http request neither related to my localhost. It was one of the component metadata templateUrl. I have mistakenly declare it like this templateUrl: '<span>Hello</span>' instead of just template: '<span>Hello</span>'
That's why the application throws exception because the component template is in bad form http://localhost:56534/%0A%20%20%20%20
I'm attempting to merge an angular and MVC application together. I'm just trying it on a blank MVC app for beginning purposes by following instructions from a course on pluralsight. However, I'm getting the following error in the console when I try to use the my app tags to test the functionality.
Pricing:56 Error: (SystemJS) XHR error (404 Not Found) loading
http://localhost:5794/src/app/app.module Error: XHR error (404 Not
Found) loading http://localhost:5794/src/app/app.module
at XMLHttpRequest.wrapFn (http://localhost:5794/node_modules/zone.js/dist/zone.js:1166:39)
at ZoneDelegate.invokeTask (http://localhost:5794/node_modules/zone.js/dist/zone.js:425:31)
at Zone.runTask (http://localhost:5794/node_modules/zone.js/dist/zone.js:192:47)
at ZoneTask.invokeTask [as invoke] (http://localhost:5794/node_modules/zone.js/dist/zone.js:499:34)
at invokeTask (http://localhost:5794/node_modules/zone.js/dist/zone.js:1540:14)
at XMLHttpRequest.globalZoneAwareCallback (http://localhost:5794/node_modules/zone.js/dist/zone.js:1566:17)
Error loading http://localhost:57594/src/app/app.module as
"./app/app.module" from http://localhost:57594/src/main.js
at XMLHttpRequest.wrapFn (http://localhost:5794/node_modules/zone.js/dist/zone.js:1166:39)
at ZoneDelegate.invokeTask (http://localhost:5794/node_modules/zone.js/dist/zone.js:425:31)
at Zone.runTask (http://localhost:5794/node_modules/zone.js/dist/zone.js:192:47)
at ZoneTask.invokeTask [as invoke] (http://localhost:5794/node_modules/zone.js/dist/zone.js:499:34)
at invokeTask (http://localhost:5794/node_modules/zone.js/dist/zone.js:1540:14)
at XMLHttpRequest.globalZoneAwareCallback (http://localhost:5794/node_modules/zone.js/dist/zone.js:1566:17)
Error loading http://localhost:5794/src/app/app.module as
"./app/app.module" from http://localhost:5794/src/main.js
Looks like it's obviously related to the zone.js file, but I can't figure this out for the life of me.
systemjs.config.js code:
/**
* System configuration for Angular samples
* Adjust as necessary for your application needs.
*/
(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/http': '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/bundles/in-memory-web-api.umd.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: 'main.js',
defaultExtension: 'js',
meta: {
'./*.js': {
loader: 'systemjs-angular-loader.js'
}
}
},
rxjs: {
defaultExtension: 'js'
}
}
});
})(this);
package.json code:
{
"name": "angular-quickstart",
"version": "1.0.0",
"description": "QuickStart package.json from the documentation, supplemented with testing support",
"scripts": {
"build": "tsc -p src/",
"build:watch": "tsc -p src/ -w",
"build:e2e": "tsc -p e2e/",
"serve": "lite-server -c=bs-config.json",
"serve:e2e": "lite-server -c=bs-config.e2e.json",
"prestart": "npm run build",
"start": "concurrently \"npm run build:watch\" \"npm run serve\"",
"pree2e": "npm run build:e2e",
"e2e": "concurrently \"npm run serve:e2e\" \"npm run protractor\" --kill-others --success first",
"preprotractor": "webdriver-manager update",
"protractor": "protractor protractor.config.js",
"pretest": "npm run build",
"test": "concurrently \"npm run build:watch\" \"karma start karma.conf.js\"",
"pretest:once": "npm run build",
"test:once": "karma start karma.conf.js --single-run",
"lint": "tslint ./src/**/*.ts -t verbose"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"#angular/common": "~4.3.4",
"#angular/compiler": "~4.3.4",
"#angular/core": "~4.3.4",
"#angular/forms": "~4.3.4",
"#angular/http": "~4.3.4",
"#angular/platform-browser": "~4.3.4",
"#angular/platform-browser-dynamic": "~4.3.4",
"#angular/router": "~4.3.4",
"angular-in-memory-web-api": "~0.3.0",
"systemjs": "0.19.40",
"core-js": "^2.4.1",
"rxjs": "5.0.1",
"zone.js": "^0.6.23"
},
"devDependencies": {
"concurrently": "^3.2.0",
"lite-server": "^2.2.2",
"typescript": "~2.1.0",
"canonical-path": "0.0.2",
"tslint": "^3.15.1",
"lodash": "^4.16.4",
"jasmine-core": "~2.4.1",
"karma": "^1.3.0",
"karma-chrome-launcher": "^2.0.0",
"karma-cli": "^1.0.1",
"karma-jasmine": "^1.0.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~4.0.14",
"rimraf": "^2.5.4",
"#types/node": "^6.0.46",
"#types/jasmine": "2.5.36"
},
"repository": {}
}
main.ts code
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
app.module.ts code:
import { NgModule } from '#angular/core';
import { APP_BASE_HREF } from '#angular/common';
import { BrowserModule } from '#angular/platform-browser';
import { ReactiveFormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { AppComponent } from './app.component';
import { routing } from './app.routing';
import { HomeComponent } from './components/home.component';
#NgModule({
imports: [BrowserModule, ReactiveFormsModule, HttpModule, routing],
declarations: [AppComponent, HomeComponent],
providers: [{ provide: APP_BASE_HREF, useValue: '/' }],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component code:
import { Component } from "#angular/core"
#Component({
selector: "user-app",
template: `
<div>
<nav class='navbar navbar-inverse'>
<div class='container-fluid'>
<ul class='nav navbar-nav'>
<li><a [routerLink]="['home']">Home</a></li>
</ul>
</div>
</nav>
<div class='container'>
<router-outlet></router-outlet>
</div>
</div>
`
})
export class AppComponent {
}
home.component.ts code
import { Component } from "#angular/core";
#Component({
template: `<img src="../../images/users.png" style="text-align:center"/>`
})
export class HomeComponent {
}
Thoughts?
I'm working an on an Ionic 2 project and my front end code renders as I would expect it on Android and web but by all accounts nothing renders correctly on iOS.
I'm using Xcode 8.0 with an iPhone 6 version 9.3.4 and Mac version 10.12
package.json
{
"name": "ionic-hello-world",
"author": "Ionic Framework",
"homepage": "http://ionicframework.com/",
"private": true,
"scripts": {
"ionic:build": "ionic-app-scripts build",
"ionic:serve": "ionic-app-scripts serve"
},
"dependencies": {
"#angular/common": "2.1.1",
"#angular/compiler": "2.1.1",
"#angular/compiler-cli": "2.1.1",
"#angular/core": "2.1.1",
"#angular/forms": "2.1.1",
"#angular/http": "2.1.1",
"#angular/platform-browser": "2.1.1",
"#angular/platform-browser-dynamic": "2.1.1",
"#angular/platform-server": "2.1.1",
"#ionic/storage": "1.1.6",
"#types/parse": "^1.2.32",
"ionic-angular": "2.0.0-rc.4",
"ionic-native": "2.2.11",
"ionicons": "3.0.0",
"rxjs": "5.0.0-beta.12",
"underscore": "^1.8.3",
"moment": "2.10.3",
"sweetalert": "1.1.3",
"zone.js": "0.6.26"
},
"devDependencies": {
"#ionic/app-scripts": "0.0.47",
"typescript": "2.0.9"
},
"cordovaPlugins": [
"cordova-plugin-device",
"cordova-plugin-console",
"cordova-plugin-whitelist",
"cordova-plugin-splashscreen",
"cordova-plugin-statusbar",
"ionic-plugin-keyboard",
"cordova-plugin-facebook4",
"cordova-plugin-nativestorage",
"parse-push-plugin"
],
"cordovaPlatforms": [
"ios",
{
"platform": "ios",
"version": "",
"locator": "ios"
}
],
"description": "CPM: An Ionic project"
}
directory.html
<ion-header class="opaque">
<ion-navbar no-border-bottom>
<ion-title class="navtitle">Directory</ion-title>
</ion-navbar>
<ion-toolbar class ="customtoolbar">
<ion-grid>
<ion-row>
<ion-segment value="filters" *ngFor="let personType of ageGender">
<ion-segment-button value="personType" >{{personType}}</ion-segment-button>
</ion-segment>
</ion-row>
</ion-grid>
</ion-toolbar>
</ion-header>
<ion-content fullscreen class="card-background-page">
<ion-list no-lines >
<ion-item *ngFor="let offer of displayOffers">
<ion-thumbnail item-left>
<img src="{{offer.get('logo')._url}}">
</ion-thumbnail>
<ion-grid>
<ion-row>
<ion-col>
<button class="listButton">Details</button>
</ion-col>
</ion-row>
</ion-grid>
<button ion-button clear item-right>{{offer.get("cashBackPercent")| percent}}</button>
</ion-item>
</ion-list>
</ion-content>
directory.ts
import { Component } from '#angular/core';
import { Parse } from 'parse-js-sdk';
import { DataService } from '../../services/dataService';
#Component({
selector: 'directory',
templateUrl: 'directory.html'
})
export class Directory {
displayOffers: any[];
ageGender: any = ["Women", "Men", "Children"];
constructor(public dataService: DataService) {}
ionViewDidLoad() {
var self = this;
this.dataService.directoryOffers().then(function(offers){
self.displayOffers = offers;
})
}
}
dataService.ts
import { Injectable } from '#angular/core';
import { Parse } from 'parse-js-sdk';
#Injectable()
export class DataService {
constructor() {
}
directoryOffers(): any{
var Offers = Parse.Object.extend("Offer");
var offerQuery = new Parse.Query(Offers);
offerQuery.equalTo("hasContract", true);
offerQuery.notEqualTo("canceled", true);
offerQuery.greaterThanOrEqualTo("untilDate", new Date());
offerQuery.include('vendor');
offerQuery.exists('logo');//display no offers that lack logos!
return offerQuery.find();
}
}
This is how it looks on web/Android:
Here is what you see on iOS:
After 10 hour of work I'm pretty certain that iOS doesn't like the change in scope represented by 'self' instead of 'this' within the query promise. Because of this I'm unable to render the data on the client.
The query returns an A+ promise and as far as I know, there is no way to resolve the promise so that the query result stands outside of the promise so that we can use 'this'. I could be totally wrong but I saw nothing in the 'Promise Resolution Procedure' that indicated otherwise.
There was a problem with the polyfills and Angular 2 being recognized on the iOS web browser.
For newbies, I'll be detailed in my answer.
First find the iOS console log:
1) Open Safari
2) Load (play button) the app via Xcode
3) Go to the develop menu
4) Select your device
5) Right before the app finishes loading you will see an option to go to your app. Do so.
From the hints in the logs I found the real error. After a search I added:
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en"></script>
to the head of my index.html above
<script src="cordova.js"></script>.