I am new with Angular. I am getting an error when I am trying to create a production build (ng build --prod). The error thrown is as follow
ERROR in Can't resolve all parameters for OpcionValor in C:/Users/Usuario/Documents/global_workspace/hcdu_proyect/HCDU_FRONT/HCDU/src/app/modulos/anamesis/anamnesis.module.ts: (?, ?)
.
ERROR in ./src/main.ts
Module not found: Error: Can't resolve './$$_gendir/app/app.module.ngfactory' in 'C:\Users\Usuario\Documents\global_workspace\hcdu_proyect\HCDU_FRONT\HCDU\src'
# ./src/main.ts 4:0-74
# multi ./src/main.ts
The file anamnesis.module.ts contains the following code:
import {NgModule} from '#angular/core';
import {CommonModule} from '#angular/common';
import {OpcionComboBox, OpcionComboBoxComplex} from '../interfaces/interfaces.module'
#NgModule({
imports: [
CommonModule,
],
declarations: []
})
export class OpcionValor implements OpcionComboBox {
constructor(private nombre: string, private valor: string) {
this.nombre = nombre;
this.valor = valor;
}
getEntityValor(): string {
return this.valor;
}
setEntityValor(valor: string) {
this.valor = valor;
}
}
export class OpcionValorObservacion extends OpcionValor implements OpcionComboBoxComplex {
observacion: string;
constructor(name: string, valor: string, observacion: string) {
super(name,valor);
this.observacion = observacion;
}
getEntityObservacion(): string {
return this.observacion;
}
setEntityObservacion(observacion: string) {
this.observacion = observacion;
}
}
export interface AnamnesisInterface {
getOpcionSeleccionadaPorNombre(nombre:string):OpcionValor;
setOpcionValorPorNombre(nombre:string, valor:string);
setOpcionValorObservacionPorNombre(nombre:string, valor:string, observacion:string);
}
I am not sure why the error is thrown if I do not have that error in dev environment. Please, somebody can help me to solve this error?
Your module is expecting two input parameters to its constructor, both of type string. Angular does not know how to construct it, most likely. I assume somewhere you have a top-level AppModule or some equivalent which looks similar to this:
#NgModule({
imports: [ OpcionValor ],
bootstrap: [ AppComponent ]
})
export class AppModule {
}
It needs to inject an OpcionValor module but can't because it doesn't know what to pass in for the constructor parameters.
I think you may need to do a little redesigning. Should nombre and valor really be members of OpcionValor, or do they belong on a Component? Should OpcionValor even be a module, or should it actually be a Component?
I had solved this issue by adding the class declaration regarding the ts file name.
The module files is called anamnesis.module.ts so I had to add the following class declaration:
export class AnamnesisModule { }
So, my module code is :
File name: anamnesis.module.ts
import {NgModule} from '#angular/core';
import {CommonModule} from '#angular/common';
import {OpcionComboBox, OpcionComboBoxComplex} from '../interfaces/interfaces.module'
#NgModule({
imports: [
CommonModule
],
declarations: []
})
**export class AnamnesisModule { }**
export class OpcionValor implements OpcionComboBox {
nombre: string;
valor: string;
constructor(nombre: string, valor?: string) {
this.nombre = nombre;
this.valor = valor;
}
..................
}
export class OpcionValorObservacion extends OpcionValor implements OpcionComboBoxComplex {
observacion: string;
constructor(name: string, valor?: string, observacion?: string) {
super(name,valor);
this.observacion = observacion;
}
.........
}
I am not sure why but it is working. I suppose there is a relation between the file name and the class declaration required.
Related
Hello I have AngularJS application which is using for internalization $translateProvider and WebResources.resx files :
angular.module('app')
.config(['$translateProvider', 'sysSettings', 'ngDialogProvider',
function($translateProvider, sysSettings, ngDialogProvider) {
ngDialogProvider.setDefaults({
closeByDocument: false
});
sysSettings.device = window['device'];
if (window['device'] && ktmvPreference && ktmvPreference.preference) {
sysSettings.webServiceURL = ktmvPreference.preference.webServiceURL;
sysSettings.reportServiceURL = ktmvPreference.preference.reportServiceURL;
sysSettings.onlineHelpURL = ktmvPreference.preference.onlineHelpURL;
}
$translateProvider.useSanitizeValueStrategy(null);
$translateProvider.useLocalStorage();
var savedLanguage = localStorage.language;
if (savedLanguage)
$translateProvider.fallbackLanguage([savedLanguage]);
else
$translateProvider.fallbackLanguage(['en', 'fr', 'es']);
var url = sysSettings.webServiceURL + 'api/GlobalResources';
$translateProvider.useUrlLoader(url);
$translateProvider.useMissingTranslationHandlerLog();
$translateProvider.useMissingTranslationHandler('ktmvTranslationFail');
}
]);
Now I am doing AngularJS/Angular5 Hybrid application. As mentioned in documentation Angular5 is using "i18n" for internationalization. "i18n" is using "*.xlf" files to keep translations.
So only way during AngularJS/Angular5 application keep both WebResources.resx and messages.xlf files with the same context ?
Is there any way to reuse WebResources.resx translation from AngularJS in AngularJS/Angular application?
Maybe it will be usefull for someone...
To be able to reuse */resx files in my AngularJS/Angular internalization I started to use ngx-translate library.
This is how I implemented it :
I created custom-translate-loader.ts
import { Injectable } from '#angular/core';
import { TranslateLoader } from '#ngx-translate/core';
import { Observable } from 'rxjs/Observable';
import {HttpClient} from "#angular/common/http";
#Injectable()
export class CustomTranslateLoader implements TranslateLoader {
constructor(private http: HttpClient) {}
getTranslation(lang: string): Observable<any>{
var apiAddress = "http://localhost:26264/api/GlobalResources/?lang=" + lang;
return Observable.create(observer => {
this.http.get(apiAddress, ).subscribe(res => {
observer.next(res);
observer.complete();
},
error => {
console.log("cannot retrieve Global Resources");
}
);
});
}
}
then in my app.module.ts I imported
import {TranslateModule, TranslateLoader} from '#ngx-translate/core';
import {HttpClient, HttpClientModule} from '#angular/common/http';
import {CustomTranslateLoader} from "./common/loader/custom-translate-loader";
and in my NgModule i injected TranslateModule :
#NgModule({
imports: [
BrowserModule,
UpgradeModule,
FormsModule,
routingModule,
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: CustomTranslateLoader,
deps: [HttpClient]
}
})
],
declarations: [
AppComponent,
SignInComponent,
ActivationComponent
],
providers: [authServiceProvider,
commonSvcProvider,
BackgroundImageFactoryProvider,
LanguageSvcProvider
// { provide: UrlHandlingStrategy, useClass: CustomHandlingStrategy }
],
bootstrap: [AppComponent]
})
After this in my components (sign-in.components.ts for example) i am able to set up the language:
import {TranslateService} from "#ngx-translate/core";
export class SignInComponent implements OnInit{
constructor(
private translate: TranslateService) {
translate.setDefaultLang('en');
}
I am trying to use this library in my application to convert JSON data to CSV file format. I installed the lib into my project as it mentions https://www.npmjs.com/package/json2csv
npm install json2csv --save.
I also see the module in my node_module folder. Then in my component class i am calling it like so
import { json2csv } from 'json2csv';
But then I get this error
[ts] Module '"c:/dev/angularworkspace/tntzweb/node_modules/json2csv/index"' has no exported member 'json2csv'.
Can someone please help me!!
Change the import to:
import * as json2csv from 'json2csv';
Then implement as:
let fields = ['field1', 'field2', 'field3'];
let result = json2csv({ data:[{ field1: 'a', field2: 'b', field3: 'c' }], fields: fields });
console.log(result);
The other answers are now outdated. For json2csv version 5, first:
npm install --save json2csv #types/json2csv
Then at the top of your Angular component/service/etc:
import { parse } from 'json2csv';
Then to generate the csv in your method:
const csv = parse(json);
There are, of course, all kinds of options you can pass to parse() and json2csv exposes other classes and functions you can import and use as well. There are useful examples in the tests from #types/json2csv.
Here is a complete CSV download implementation:
<a [download]="csvFileName" [href]="getCSVDownloadLink()">CSV export</a>
import { Component } from '#angular/core';
import { DomSanitizer } from '#angular/platform-browser';
import * as json2csv from 'json2csv';
#Component({
selector: 'csv-download',
templateUrl: './csv-download.component.html',
styleUrls: ['./csv-download.component.scss']
})
export class CsvDownloadComponent {
public csvFileName = `test.csv`;
private SOME_DATA: any[] = [{id: 1, name: 'Peter'}, {id: 2, name: 'Sarah'}];
constructor(
private domSanitizer: DomSanitizer,
) { }
getCSVDownloadLink() {
return this.generateCSVDownloadLink({
filename: this.csvFileName,
data: this.SOME_DATA,
columns: [
'id',
'name',
],
});
}
// you can move this method to a service
public generateCSVDownloadLink(options: { filename: string, data: any[], columns: string[] }): SafeUrl {
const fields = options.columns;
const opts = { fields, output: options.filename };
const csv = json2csv.parse(options.data, opts);
return this.domSanitizer.bypassSecurityTrustUrl('data:text/csv,' + encodeURIComponent(csv));
}
}
You can use the angular 2 version of the library. The link to the same is: https://github.com/aqeel-legalinc/angular2-json2csv
I'm trying to use dependancy injection in angular using an injector. I want to me able to instantiate types at runtime depending on what this component is sent.
#Injectable()
export class ServiceInjectionManager {
private _injector: ReflectiveInjector;
constructor() {
this._injector = ReflectiveInjector.resolveAndCreate([
MockBackend,
BaseRequestOptions,
{
provide: Http,
useFactory: (backendInstance: MockBackend, defaultOptions: BaseRequestOptions) => {
return new Http(backendInstance, defaultOptions);
},
deps: [MockBackend, BaseRequestOptions]
},
AppSettings,
HierarchyService
]);
}
public resolve<T extends HierarchyService>(type:any): T {
return this._injector.get(type);
}
}
I can't seem to find a way to pass a type. I have taken multiple approaches including:
public resolve<T extends HierarchyService>(T): T {
return this._injector.get(T);
}
It seems that generics in TypeScript are not the same as in .NET.
JIT-compilation is worked. But, I decided to compile application using the
AOT-compilation. And I get the following error:
Cannot determine the module for class ProfileComponent
Cannot determine the module for class ProfileComponent
Cannot determine the module for class ProfileRESTService
My application consists of single module. At the same time, it has a lot of components and services. These are described in a single #NgModule. Variable MODULES contains array components and services, there's no #NgModule, just a array classes, almost.
modules.ts
...
import {ProfileModule} from './profile/module';
export const MODULES = [
...
ProfileModule
];
profile/module.ts
...
import {ProfileComponent} from "./component/Profile/index";
import {ProfileRoute} from "./route/ProfileRoute/index";
import {ProfileRESTService} from "./service/ProfileRESTService";
export const ProfileModule = [
declarations: [
...
ProfileComponent
],
routes: [
...
ProfileRoute
],
providers: [
...
ProfileRESTService
]
]
app.module.ts
import {App} from './app.component';
import {routing} from "./app.routing";
import {MODULES} from "./module/modules";
let moduleDeclaration = {
declarations: [
App
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [
BrowserModule,
routing,
FormsModule,
ReactiveFormsModule,
HttpModule,
]
bootstrap: [App]
};
for (let module of MODULES) {
if (!!module['declarations'] && module['declarations'] instanceof Array) {
for (let item of module['declarations']) {
moduleDeclaration.declarations.push(item)
}
}
if('routes'){...}
if('providers'){...}
if('imports'){...}
}
#NgModule(moduleDeclaration)
export class AppModule {}
I suppose that when AOT compilation, analyzes the object that is passed in #NgModule, in my case, this object is not yet ready. It will be difficult to re-write the application describing each module as #NgModule. How can I solve the problem with the dynamic executable moduleDeclaration?
I have TypeScript code:
// app.js
import * as angular from 'angular';
import { Deamon } from 'Deamon';
angular.module('app')
.service('deamon', DeamonClass);
// Deamon.ts
export class DeamonClass {
$inject = [
'$vk'
];
constructor(private $vk: any) {} // <- $vk is my another service VkClass
}
How do I specify the type from $vk? If I point as the type name of the class,
constructor(private $vk: VkClass) {}
then nothing does not compile.