Angular 5 HttpClientModule console error when imported - asp.net-mvc

I've begun a project using Angular5 inside a ASP.NET MVC project. I've been following the official tutorial on the Angular site, just to get my feet wet, and it's been great until now.
I've gotten to the end of the tutorial, using the Http module, but I can't get the module imported. When I add the HttpClientModule into the the imports list I get this console error:
Error: Unexpected token <
Evaluating http://localhost:54129/node_modules/#angular/common/bundles/common.umd.js/http
Evaluating http://localhost:54129/app/app.module.js
Evaluating http://localhost:54129/app/main.js
Loading app/main.js
at eval ()
at evaluate (evaluate.js:106)
at instantiate.js:394
at dynamicExecute (register-loader.js:665)
at doEvaluate (register-loader.js:612)
at ensureEvaluate (register-loader.js:520)
at register-loader.js:538
at Object.eval (:54129/app/app.module.js:12)
at eval (:54129/app/app.module.js:34)
at eval (:54129/app/app.module.js:35)
(anonymous) # localhost/:20
With some searching I found that I maybe needed to include:
'#angular/common/http': 'npm:#angular/common/bundles/common-http.umd.js',
'tslib': 'npm:tslib/tslib.js'
into my systemjs.config.js file, which I have done, but it hasn't resolved the error.
Here's my app.module.ts:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { HttpClientModule } from '#angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AccountInfoComponent } from './AccountInfo/AccountInfoComponent';
import { VehicleComponent } from './Vehicle/VehicleComponent';
import { UserService } from './Services/UserService';
import { CustomerService } from './Services/CustomerService';
#NgModule({
imports: [BrowserModule, FormsModule, AppRoutingModule, HttpClientModule],
declarations: [AppComponent, AccountInfoComponent, VehicleComponent],
bootstrap: [AppComponent],
providers: [UserService, CustomerService]
})
export class AppModule { }
And my systemjs.config.js:
/**
* 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/common/http': 'npm:#angular/common/bundles/common-http.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
'tslib': 'npm:tslib/tslib.js',
'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: {
defaultExtension: 'js',
meta: {
'./*.js': {
loader: 'systemjs-angular-loader.js'
}
}
},
rxjs: {
defaultExtension: 'js'
}
}
});
})(this);
Any idea what I'm missing or what I'm doing wrong?

This error could be caused how it's being built (with, I assume, the angular CLI(. What flags are you using on ng build? Check out the file names in the angular CLI destination directory. In the dev build, the files are called "inline.bundle.js"; in the production build, cache busting is implemented, so they have funky names like "inline.d78byc79tcnuasdf.bundle.js".
Something like this should work:
ng build --prod --ec=false --oh=media
This keeps the scripts and styles in the same format as in development.
The diferent flags for prod and dev builds are discussed in the docs here: https://github.com/angular/angular-cli/wiki/build#--dev-vs---prod-builds

Related

How to use quasar framework in vuepress 2?

I'm now using vuepress2 with quasar 2.7.1 like this:
import { Quasar } from 'quasar';
export default defineClientAppEnhance(({ app, router, siteData }) => {
app.use(Quasar);
}
#import url(https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons|Material+Icons+Outlined);
#import 'quasar/src/css/variables.sass';
#import 'quasar/src/css/core/colors.sass';
.quasar-comp {
#import 'quasar/src/css/index.sass';
}
/* I wrap the custome component in class .quasar-comp
so that the style from quasar won't conflict with style from vuepress. */
but there are 2 issues:
The style from quasar cannot works on some components, like q-btn-dropdown or q-menu.
It works well on dev mode(npm run docs:dev), but failed to build(npm run docs:build).
✔ Compiling with vite - done
✖ Rendering pages - failed
TypeError: Cannot convert undefined or null to object
at Function.assign (<anonymous>)
at installQuasar (/Users/lxm/Documents/neo/leaneo-docs/node_modules/quasar/dist/quasar.cjs.prod.js:6:15228)
at Object.install (/Users/lxm/Documents/neo/leaneo-docs/node_modules/quasar/dist/quasar.cjs.prod.js:6:479348)
at Object.use (/Users/lxm/Documents/neo/leaneo-docs/node_modules/#vue/runtime-core/dist/runtime-core.cjs.prod.js:3393:28)
at /Users/lxm/Documents/neo/leaneo-docs/docs/.vuepress/dist/.server/app.js:3745:7
at createVueApp (/Users/lxm/Documents/neo/leaneo-docs/docs/.vuepress/dist/.server/app.js:4177:11)
at async /Users/lxm/Documents/neo/leaneo-docs/node_modules/vuepress-vite/node_modules/#vuepress/bundler-vite/lib/build/build.js:49:52
at async /Users/lxm/Documents/neo/leaneo-docs/node_modules/#vuepress/utils/lib/withSpinner.js:12:24
at async build (/Users/lxm/Documents/neo/leaneo-docs/node_modules/vuepress-vite/node_modules/#vuepress/bundler-vite/lib/build/build.js:34:5)
at async /Users/lxm/Documents/neo/leaneo-docs/node_modules/#vuepress/cli/lib/commands/build/createBuild.js:51:5
Is there a better way to make quasar and vuepress works together?
Here is the implementation in Vuepress 2 (beta) and Quasar with Typescript.
First, install Quasar into Vuepress with the new syntax and import all styles:
client.ts:
import { defineClientConfig } from "#vuepress/client";
import { Quasar } from "quasar";
import 'quasar/src/css/index.sass';
export default defineClientConfig({
enhance({app, router, siteData}) {
app.use(Quasar);
},
setup() {},
rootComponents: [],
});
Then, ignore deprecation errors from sass if you're using vite.
config.ts
import { viteBundler } from '#vuepress/bundler-vite'
import { defineUserConfig } from '#vuepress/cli'
export default defineUserConfig({
// your config
...
bundler: viteBundler({
viteOptions: {
css: {
preprocessorOptions: {
scss: {
sassOptions: {
// ignore sass deprecation errors
quietDeps: true
}
}
}
}
},
}),
});
Hope it helps :)
Quasar needs some globales to be defined (ie if it's SSR). My following solution works ONYL on client-side so be sure to wrap your custom-quasar component in <ClientOnly> !
// .vuepress/config.ts
bundler: viteBundler({
viteOptions: {
define: {
__QUASAR_VERSION__: `'dev'`,
__QUASAR_SSR__: false,
__QUASAR_SSR_SERVER__: false,
__QUASAR_SSR_CLIENT__: false,
__QUASAR_SSR_PWA__: false
}
}
}),
// .vuepress/client.ts
import { defineClientConfig } from '#vuepress/client'
import Quasar from "quasar/src/install-quasar.js";
// optionally import your styles here
// import 'quasar/src/css/index.sass';
export default defineClientConfig({
enhance({ app, router, siteData }) {
app.use(Quasar);
},
setup() {
},
rootComponents: [],
});
<!-- README.md -->
<ClientOnly>
<MyComponent />
</ClientOnly>

Notifications failing at notify()

I am trying to fire a simple notification in Quasar 2:
setup() {
const $q = useQuasar()
$q.notify('hello')
}
This fails with:
Uncaught TypeError: $q.notify is not a function
This is a UMD application that works fine without these two lines - I do not really know where to go from there as the docs say that there is nothing special to configure before using it.
Incindentally, my IDE is suggesting me notify() when typing $q. so at least at that level is it well recognized.
I think you forgot to add notify in plugins(quasar.conf.js).
return {
framework: {
plugins: [
'Notify'
],
}
}
For those using Vue CLI, you will need to work on quasar-user-options.js:
import { Notify } from "quasar";
// To be used on app.use(Quasar, { ... })
export default {
plugins: { Notify },
};
Quasar vite plugin + vue3
In main.ts or main.js, just add these 2 lines :
JS
import { Notify } from "quasar";
.use(Quasar, {
plugins: {
Notify,
}, // import Quasar plugins and add here
})
Here a example of my code :
JS
import { createApp } from 'vue'
import { Quasar } from 'quasar'
import quasarLang from 'quasar/lang/fr'
import { Notify } from "quasar";
import router from './router'
import { createPinia } from 'pinia'
import './style.css'
// Import icon libraries
import '#quasar/extras/material-icons/material-icons.css'
// Import Quasar css
import 'quasar/src/css/index.sass'
import App from './App.vue'
const pinia = createPinia()
createApp(App)
.use(Quasar, {
plugins: {
Notify,
}, // import Quasar plugins and add here
lang: quasarLang,
})
.use(router)
.use(pinia)
.mount('#app')

Ionic 4 IOS Socket.io how to get config dynamically

I'm programming an application with ionic and socket IO, in the app.module.ts the import of the socket needs a config for the url and options. This is hardcoded and i would like have this config dynamically from a form or a storage. I dont want to deploy the application for any change of the ip address or server port and i dont want to use a dns link.
Can you tell me how I can do that ?
I'm using ionic : 5.4.5, Cordova 9.0.0 and deploy on IOS 12.4
Here is my app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouteReuseStrategy } from '#angular/router';
import { ErrorHandler } from '#angular/core';
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule } from '#angular/common/http';
import { SocketIoModule, SocketIoConfig } from 'ng-socket-io';
const config: SocketIoConfig = { url: 'http://192.168.0.17:3001', options: {} };
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
HttpClientModule,
SocketIoModule.forRoot(config),
],
providers: [
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule { }
Thanks for any response.
app.module.ts is your core application module and it should load fast to allow other modules and components to get ready asap. So adding business logic to it to fetch dynamic config for Socket.io might be suboptimal as you may cause UX issues (longer load time etc).
I would suggest moving the initialization/config of the socket.io away from app.module.ts to another module that gets loaded later in the start-up life cycle of your app.
I had similar requirement and I approached it this way:
-used other socket.io client library that does not require init via a module: https://github.com/socketio/socket.io-client
-created a service and imported this library into it:
import { Injectable } from "#angular/core";
import io from "socket.io-client";
export class FoundationProvider {
public sockets;
}
-created a method that is called after I fetched socket config details and other details from persistence:
initSocketsIO() {
if (this.data.userID && this.state.appIsOnline) {
this.sockets = io(
this.config.apiBaseUrl + "?_id=" + this.data.userID,
{
reconnectionAttempts: 3,
reconnectionDelay: 10000,
transports: ['websocket']
}
)
this.sockets.on("snippets", event => {
this.handleIncomingNotification(event.message);
})
this.sockets.on("tasks", event => {
this.handleIncomingNotification(event.message);
})
this.sockets.on("payments", event => {
this.handleIncomingNotification(event.message);
})
};
};
If you still need your current library to work - then you may need to try moving it to another suitable module that loads later in your app start life cycle when global configs and variables are already available across the application. Hope this helps.

'mat-toolbar' is not a known element - Angular 5

I have created a new project, and I am trying to add angular-material.
I have created material.module.ts in my app folder:
import { NgModule } from '#angular/core';
import {
MatButtonModule,
MatMenuModule,
MatIconModule,
MatCardModule,
MatSidenavModule,
MatFormFieldModule,
MatInputModule,
MatTooltipModule,
MatToolbarModule
} from '#angular/material';
#NgModule({
imports: [
MatButtonModule,
MatMenuModule,
MatIconModule,
MatCardModule,
MatSidenavModule,
MatFormFieldModule,
MatInputModule,
MatTooltipModule,
MatToolbarModule,
],
exports: [
MatButtonModule,
MatMenuModule,
MatIconModule,
MatCardModule,
MatSidenavModule,
MatFormFieldModule,
MatInputModule,
MatTooltipModule,
MatToolbarModule
]
})
export class MaterialModule { }
and I have imported it into one of my components:
import { MaterialModule } from '../material.module';
Furthermore, I have set up angular material in index.html
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
in my style.css
#import '~#angular/material/prebuilt-themes/pink-bluegrey.css';
I know that it is working cause I have shown a material-icon as a test:
<i class="material-icons">face</i>
but when I try to create the footer it fails and it shows this message:
Uncaught Error: Template parse errors:
'mat-toolbar' is not a known element:
1. If 'mat-toolbar' is an Angular component, then verify that it is part of this module.
2. If 'mat-toolbar' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
That's because you have to import a module to the module which contains the component declaration, not into the component itself:
app.module.ts
import { MaterialModule } from './material.module';
#NgModule({
imports: [
// ...
MaterialModule
],
declarations: [
MyCoolComponent,
// ...
]
})
P.S. The correct way to use a material icon is to use the MatIcon component. Example usage:
<mat-icon>home</mat-icon>
Best way
for a quick good fix
import {MatToolbarModule} from '#angular/material/toolbar';
in your app.module.ts
then declare MatToolbarModule in your declarations[].
Works fine for me here: https://stackblitz.com/edit/angular-w9ckf8
Look over the link and see if there's anything you are missing.
run ng add #angular/material in your terminal and this will fix your error
You need to import import {MatToolbarModule} from '#angular/material/toolbar'; and add it in imports array. Also the code for material is maintained in https://github.com/angular/components.
I got the same error, I realized it was my fault.
I was getting this error because I didn't make the following definition to the App component.
app.module.ts
#NgModule({
declarations: [
AppComponent,
DataTableComponent,
PeriodicComponent,
HeaderComponent -- here is using MatToolbarModule.
],
first you have to add the component that uses material dizany component to declarations array.
I have resolved this issue by making strict as false
Open
tsconfig.json
{ "compilerOptions" : { "strict" : false} }
Note:
I have imported MatToolbarModule too
import {MatToolbarModule} from '#angular/material/toolbar';
and declared in Imports array

angular 2 with mvc 5 bootstrap a component

Our site is an existing MVC site and we are working on adding and replacing some parts with angular 2 components. We do not have a full angular 2 app to launch, so we are just using bootstrap to launch our components on the pages we want them.
I updated my package.json dependencies from "2.0.0-rc.1" to "~2.2.0" and now have the latest angular 2 files. I can no longer use import { bootstrap } from '#angular/platform-browser-dynamic' and launch my component with: bootstrap(MyCountComponent, [HTTP_PROVIDERS, MyService]);.
Searching it seems to have been updated to import { platformBrowserDynamic } from '#angular/platform-browser-dynamic'; and now I should launch with: platformBrowserDynamic().bootstrapModule(MyCountComponent, [HTTP_PROVIDERS, MyService]);
When I do this I'm getting the browser Console error:
Unhandled Promise rejection: (SystemJS) No NgModule metadata found for 'MyCountComponent'.
Error: No NgModule metadata found for 'MyCountComponent'...
Do I need to convert my components to modules now or is there a new way to bootstrap launch the components without a module?
Here is a code sample.
//mycount.ts
import { MyService } from '../../services/my.service';
import { HTTP_PROVIDERS } from '#angular/http';
import { bootstrap } from '#angular/platform-browser-dynamic'
import { MyCountComponent } from './mycount.component';
bootstrap(MyCountComponent, [HTTP_PROVIDERS, MyService]);
//mycount.component.ts
import { Component } from '#angular/core';
import { NgControl } from '#angular/forms';
import { MyService } from '../../services/my.service';
#Component({
selector: 'mycount',
templateUrl: './app/components/mycount/mycount.component.html'
})
export class MyCountComponent {
constructor(private _myService: MyService) {
}
get mycount() {
return this._myService.mycount;
}
}
//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/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',
'#angular/upgrade': 'npm:#angular/upgrade/bundles/upgrade.umd.js',
'#angular/upgrade/static': 'npm:#angular/upgrade/bundles/upgrade-static.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'
},
rxjs: {
defaultExtension: 'js'
}
}
});
})(this);
EDIT
If I have:
#NgModule({
imports: [
BrowserModule,
FormsModule,
HttpModule
],
bootstrap: [MyCountComponent, MyListComponent, MyDetailsComponent],
declarations: [MyCountComponent, MyListComponent, MyDetailsComponent],
exports: [MyCountComponent, MyListComponent, MyDetailsComponent],
providers: [MyService]
})
Is it possible for my page to only load 1 or 2 of the components?
I tried calling it with:
platformBrowserDynamic().bootstrapModule(MyModule, [HttpModule, MyListComponent]);
but I get an error message for any component tags missing from the page.
you need to create main #NgModule where you can import all Services, Components, Directives etc. using #NgModule you can tell your app that which component should bootstrap.
here is official links to understand that #ngModule please go through this: https://angular.io/docs/ts/latest/guide/ngmodule.html
Tips: please use Angular-cli which will create a basic structure of app just in few minutes. using Angular-cli you no need to create structued app or basic setup it will do it for you.

Resources