In order to migrate an Angular 5 project to Angular 8, I've created an empty project with Angular CLI and copied my modules, components and services in my new project structure.
The project builds, but at the execution I've got the classic message "No provider for HttpClient in service" :
ERROR NullInjectorError: StaticInjectorError(AppModule)[TimeService -> HttpClient]:
StaticInjectorError(Platform: core)[TimeService -> HttpClient]:
NullInjectorError: No provider for HttpClient!
at NullInjector.get (http://localhost:4200/vendor.js:50573:27)
at resolveToken (http://localhost:4200/vendor.js:52359:24)
at tryResolveToken (http://localhost:4200/vendor.js:52285:16)
at StaticInjector.get (http://localhost:4200/vendor.js:52148:20)
at resolveToken (http://localhost:4200/vendor.js:52359:24)
at tryResolveToken (http://localhost:4200/vendor.js:52285:16)
at StaticInjector.get (http://localhost:4200/vendor.js:52148:20)
at resolveNgModuleDep (http://localhost:4200/vendor.js:76198:29)
at _createClass (http://localhost:4200/vendor.js:76275:32)
at _createProviderInstance (http://localhost:4200/vendor.js:76231:26)
I thing my app.module.ts is ok : I'm importing HttpClientModule and I've put it in #NgModule imports, just after BrowserModule.
#NgModule({
declarations: [AppComponent,DelegationsComponent],
imports: [BrowserModule,
HttpClientModule,
GlobalModule.forRoot(),
AuthenticationModule,
DelegationModule,
routing,
FormsModule,
ReactiveFormsModule,
BrowserAnimationsModule,
ButtonModule, TableModule, DialogModule, DropdownModule, ToastModule, TabViewModule, InputTextModule, AutoCompleteModule, TooltipModule, CheckboxModule, OverlayPanelModule, MultiSelectModule, CalendarModule ],
providers: [APP_ROUTER_PROVIDERS, {provide: APP_BASE_HREF, useValue: getBaseHref()}],
bootstrap: [AppComponent]
})
The error seems to be in TimeService. In this service, HttpClient is imported and injected in the contructor.
import {HttpClient} from "#angular/common/http";
#Injectable()
export class TimeService extends BaseService {
constructor(private http: HttpClient)
Then, TimeService is injected in DelegationsComponent.
import {TimeService} from "utils/time.service";
#Component({
moduleId: __moduleName,
selector: 'delegations',
templateUrl: './delegations.component.html'
})
export class DelegationsComponent implements OnInit, OnDestroy {
constructor(private timeService: TimeService)
And you can see DelegationsComponent in my app.module.ts declarations.
Any idea ?
Thank you
EDIT :
By trying to reproduce the problem on a small example, I've found the cause : time.service.ts is not in my angular app but in a folder outside, because I'm sharing it with two other angular apps. I'm including it thanks to the package.json of my apps :
"utils": "file:../../../../../utils"
So time.service.ts ends in node_modules/utils. If I put it in the src/app directory, it works. Any idea why it doesn't work this way, and how I can share a service amongst several angular apps ?
The error =>
ERROR NullInjectorError: StaticInjectorError(AppModule)[TimeService -> HttpClient]:
StaticInjectorError(Platform: core)[TimeService -> HttpClient]:
Below solution is worked for me and I am using Angular version-9
=> Need to add => import {HttpClientModule} from '#angular/common/http'; in app.module.ts and also in the [import] array.
You need to provide your service in the root (or the components you desire) in order to inject it in the application. Otherwise, the imported HttpClientModule will not be imported for the injectable.
For providing in the root, use providedIn property like following:
#Injectable({
providedIn: 'root'
})
export class TimeService extends BaseService {
constructor(private http: HttpClient){}
}
If you want to provide a service in a component, then you need to set it in providers property of component decorator like following:
#Component({
moduleId: __moduleName,
selector: 'delegations',
templateUrl: './delegations.component.html',
providers: [
TimeService
]
})
export class DelegationsComponent implements OnInit, OnDestroy {
constructor(private timeService: TimeService){}
}
Then import TimeService and HttpClientModule in app.module.ts (or in your feature module).
You can find a working example here: https://stackblitz.com/edit/angular-bzvgwn
import this inside your app.module.ts.This will work
import { HttpModule } from "#angular/http";
Related
The following is my problem.
I packaged my project through vite in library mode. The error occurs whenever my library includes any third party UI library (e.g vue-loading-overlay). But other libraries like moment.js will have no problem.
This is my vite.config.js, Is there any problem with my configuration?
import { defineConfig } from "vite";
import vue from "#vitejs/plugin-vue";
export default defineConfig({
plugins: [vue()],
build: {
lib: {
entry: resolve(__dirname, "src/lib.ts"),
name: "my-ui-lib",
fileName: "my-ui-lib",
},
rollupOptions: {
external: ["vue"],
output: [
{
format: "es",
exports: "named",
globals: { vue: "vue" },
},
],
},
},
});
Finally I resolved my problem, Adding the following in vite.config.js. It works for me.
build: {
/** If you set esmExternals to true, this plugins assumes that
all external dependencies are ES modules */
commonjsOptions: {
esmExternals: true
},
}
Original Answer
"Chart.js V3 is treeshakable so you need to import and register everything or if you want everything you need to import the chart from the auto import like so:
change
import Chart from 'chart.js'
to ->
import Chart from 'chart.js/auto';
For more information about the different ways of importing and using chart.js you can read the integration page in the docs.
Since you are upgrading from Chart.js V2 you might also want to read the migration guide since there are some major breaking changes between V2 and V3"
/* Adding the following in vite.config.js. Just copy and paste all these code. It works for me. */
import { defineConfig } from "vite";
import react from "#vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
commonjsOptions: {
esmExternals: true,
},
});
react-pdf v6 has a pretty clever solution for this, look at their entry files. I think the point is to link to the correct file, somehow there's no need to "actually" import the worker (it doesn't run on main thread anyway I guess? New to worker and pdfjs).
import * as pdfjs from 'pdfjs-dist/build/pdf';
pdfjs.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.js', import.meta.url);
import.meta availability.
Refer to vuejs 3 documentation to import vue.
I had to manually upgrade from 3.2 to 4.2 and because I am developing a Angular library, I could not use the schematics to perform the update.
I have got it working on the development build. We are developing a feature library that targets the checkout (Payment Page and Order Confirmation Page) and it works fine.
With the production build (ng build --configuration production), the payment page works fine, but the Order Confirmation page is not working. it complains that orderCore feature is not configured properly.
Note: we are being redirected from an external site, back to the order confirmation page (after authorization). When the page loads, it shows the following error in the log and show a broken my account page.
core.js:6498 ERROR Error: Feature orderCore is not configured properly
at FacadeFactoryService.getResolver (spartacus-core.js:24825)
at FacadeFactoryService.create (spartacus-core.js:24867)
at facadeFactory (spartacus-core.js:24898)
at orderReturnRequestFacadeFactory (spartacus-order-root.js:13)
at Object.factory (spartacus-order-root.js:37)
at R3Injector.hydrate (core.js:11457)
at R3Injector.get (core.js:11276)
at NgModuleRef$1.get (core.js:25352)
at Object.get (core.js:25066)
at lookupTokenUsingModuleInjector (core.js:3354)
Anyone has an idea if we are missing some configuration in the feature modules?
import { NgModule } from '#angular/core';
import { checkoutTranslationChunksConfig, checkoutTranslations } from '#spartacus/checkout/assets';
import { CHECKOUT_FEATURE, CheckoutRootModule } from '#spartacus/checkout/root';
import { CmsConfig, I18nConfig, provideConfig } from '#spartacus/core';
#NgModule({
declarations: [],
imports: [
CheckoutRootModule,
],
providers: [provideConfig({
featureModules: {
[CHECKOUT_FEATURE]: {
module: () =>
import('#spartacus/checkout').then((m) => m.CheckoutModule),
}
},
} as CmsConfig),
provideConfig({
i18n: {
resources: checkoutTranslations,
chunks: checkoutTranslationChunksConfig,
},
} as I18nConfig)
]
})
export class CheckoutFeatureModule {
}
My colleague has provided a proposal:
If you want to use Spartacus Order library, you need to create "order-feature.module.ts" for it. And by default core is bundled together with components. So, in your configuration, you need have this set: "[ORDER_CORE_FEATURE]: ORDER_FEATURE". So, the config is something like this:
const config: CmsConfig = {
featureModules: {
[ORDER_FEATURE]: {
cmsComponents: [
....
],
},
// by default core is bundled together with components
[ORDER_CORE_FEATURE]: ORDER_FEATURE,
},
};
I have followed the instructions on https://github.com/Justineo/vue-awesome
in my jest.config.js I add the following
transformIgnorePatterns: [
'/node_modules(?![\\\\/]vue-awesome[\\\\/])/'
]
my nuxt.config.js
build: {
transpile: [/^vue-awesome/] // enable font-awesome integration.
},
The icons work just fine when I'm running the dev box, but I get the following when I run yarn test:
[path/to/project]/node_modules/vue-awesome/icons/building.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import Icon from '../components/Icon.vue'
^^^^^^
SyntaxError: Cannot use import statement outside a module
explicitly, the issue seems to be something to do with how babel reads (or overlooks) the imports above the Icon component import. So, for example, given the building.js in the error log above, here is how the import looks in the vuejs file:
<script>
import 'vue-awesome/icons/building'
import Icon from 'vue-awesome/components/Icon'
export default {
componentes: {
'v-icon': Icon
}
...
}
</script>
It looks like I have to explicitly mock the component and its imports at the top of the file (below the imports)
the following works for my test.
import { shallowMount, createLocalVue } from '#vue/test-utils'
import Vuex from 'vuex'
import { AxiosSpy, MockNuxt } from 'jest-nuxt-helper'
import index from '#/pages/courses/index'
// MOCKS:
jest.mock('vue-awesome/icons/building', () => '')
jest.mock('vue-awesome/components/Icon', () => '<div></div>')
...
I'm new to Ionic 4 and am trying to get SQLite working. I have added the cordova plugin and the ionic native sqlite but when I try and set it up in the app module I get the above error. Here is my app,module.ts
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 { IonicStorageModule } from '#ionic/storage';
import { SQLite } from '#ionic-native/sqlite';
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule, IonicModule.forRoot(), IonicStorageModule.forRoot(), AppRoutingModule],
providers: [
StatusBar,
SplashScreen,
SQLite,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule {}
Can anyone help?
You have to import from '#ionic-native/sqlite/ngx'
https://ionicframework.com/docs/native
It looks like this has to do with the recent release of Ionic 4. I ran into this issue with #ionic-native/file within my app. If you installed after the release without specifying the version you wanted, you probably got the latest or beta version.
I was able to fix it by rolling back to an earlier version by modifying my package.json to reflect the version required -- I had 5.0.0 installed and rolled back to 4.20.0. If you have VersionLens for VSCode it will show you the minimum and the latest versions.
Then, clear your node modules, and reinstall:
rm -rf node_modules/
npm install
There is another post open this, available here:
Type HTTPOriginal is not assignable to type Provider, ionic error after plugin installation
It happens because of the new update of ionic 4.
You have to add /ngx to your plugin's import. Like this:
import { PluginName} from '#ionic-native/pluginName/ngx';
Otherwise fallback to ionic v4.
More info here
Everywhere where native plugins are imported, you need to add /ngx/.
Moreover, this must be done throughout the project, otherwise the error will still appear.
Error example:
import {Market} from '#ionic-native/market';
True example:
import {Market} from '#ionic-native/market/ngx';
Import:
import { SQLitePorter } from '#ionic-native/sqlite-porter/ngx';
import { SQLite } from '#ionic-native/sqlite/ngx';
And add into provider:
providers: [
SQLite,
SQLitePorter
]
This usually happens if you import them from different path.
You have to import '#ionic-native/sqlite/ngx' at both app.module.ts and the page you want to use it.
I'm working on a vuejs project and we're trying to use external vue cli applications as libraries. In these libraries we want to be able to export a router config, which lazy loads the components within one of these modules. However when we compile this using the vue-cli-service into a library and it's got lazy chunk assets we cannot resolve them with webpack.
I have a feeling its something to do with the public path, or some simple configuration but i'm just stuck and banging my head against a wall at this stage with it.
https://github.com/EvanBurbidge/mono-repo-tester
Here's a simple overview of what we're doing
App1 -> main app, installs App2, imports { router } from 'app2'
App2 -> library, compiles to common js lib exports router config
The console output from app1
The router configuration from app2
The router importing app2 from app1
/* config.module.rule('js') */
{
test: /\.jsx?$/,
exclude: [
function () { /* omitted long function */ }
],
use: [
/* config.module.rule('js').use('cache-loader') */
{
loader: 'cache-loader',
options: {
cacheDirectory: '/Users/evan/test/node_modules/.cache/babel-loader',
cacheIdentifier: '39e7e586'
}
},
/* config.module.rule('js').use('babel-loader') */
{
loader: 'babel-loader'
}
]
},
I think I know what the problem is.
It appears that you're suffering from the fact that the default config of webpack bundled with VueJS does not support what you are trying to accomplish. In fact, it may very well be that Webpack does not support what you are trying to accomplish #2471 #6818 #7843.
When you compile app2 into UMD and try to use it within app1 by importing the UMD, the dynamic imports of app2 are not being resolved and are thus not copied over to the publicPath of app1. Since it is a dynamic import, compilation succeeds to the point where you can deploy the app. When you try to load the app however, it starts complaining that chunks are missing.
Here's one way to solve this problem:
app2/package.json
{
"name": "app2",
...
"main": "src/router.js"
}
app2/src/router.js
const Hey = () => import(/*webpackChunkName: 'app2.Hello.vue' */ './components/HelloWorld.vue')
export default [
{
path: '/app2',
component: Hey,
name: 'app2.hey'
}
]
app1/router.js
import app2Router from 'app2'
import Home from './views/Home.vue'
export default new Router([
mode: 'history',
...
routes: [
{
path: '/',
name: 'home',
component: Home
},
...app2Router
]
])
By marking the main or module of app2/package.json as router.js instead of the the UMD bundle, you are forcing app1 to build the whole dependency graph and include any dynamic import that is detected. This in turn causes the dependencies to be copied over properly.
You could also achieve the exact same results by using
import app2Router from 'app2/src/router'
Supposedly, this issue is now fixed in Webpack 5 https://github.com/webpack/webpack/issues/11127