ng2-material-select
ng2-material-select copied to clipboard
ERROR in Ng2SelectModule is not an NgModule
I know this has been reported before, but i just need ASAP clarification if the problem is bug with the module implementation or it's an ng-cli / webpack bug?
I'm on those versions "angular-cli": "1.0.0-beta.24", "@angular/compiler-cli": "^2.3.1", "typescript": "^2.0.10", "@angular/common": "^2.3.1",
thanks
i have created a rep with the error https://github.com/mhmo91/ERROR-in-is-not-an-NgModule
also, check my comment on this thread https://github.com/angular/angular-cli/issues/3426#issuecomment-268955509
@mhmo91 did you get this resolved? I'm having the same issue.
@playground
I didn't, my solution was shifting to another component. here's the alternatives
1- Material Select: currently at the moment it the best one outthere but doesn't support multiselect
https://material.angular.io/components/component/select
2- ng2 select
https://www.npmjs.com/package/angular2-select
3- Another ng2 select
https://www.npmjs.com/package/ng2-select
I do hate it when someone create something for the opensource community and doesn't maintain it!
Hi @playground,
the reason is you may be trying to compile it with ngc
? This component does not support this yet, but I will work on it as soon as I can.
@mhmo91 I understand the frustration, but:
- I am not paid to write open source code, so I do it in my free time, therefore I do it when I can
- open source means everyone can contribute - maintainer need help sometime, but haven't seen a PR?
So believe me, if I could I'd write OSS all the time, but this world expects me to pay the bills too, so.
@Gbuomprisco I totally understand ur point but with great power comes great responsibility 💃 i'm sorry if i sounded rude i didn't mean that ^^, anywayyss, thanks for ur work anyway :))
@mhmo91 no worries :) I'll keep the thread up to date if there are news
@Gbuomprisco thanks for the note and your work. Do you have an idea of the timeline?
Meanwhile @mhmo91, I'm trying out https://material.angular.io/components/component/select, but having trouble setting the default value and when select from the dropdown, the model(item.redirectCode) is not getting updated. It seems to work with older version of cli. Any idea? Here is my template.
<md-select placeholder="Enter redirect code" name="redirectCode" [(ngModel)]="item.redirectCode" ngModelOptions="{trackBy: '$value.id'}"> <md-option ngValue="code" *ngFor="let code of codes" ngSelected="item.redirectCode === code"> {{code}}
@playground replace ngValue with [value] i'm not sure about the ngModelOptions, where did u get this from :D for more info, check the examples tab
Thanks @mhmo91 that works.
@Gbuomprisco @playground
I have solved it by adding @NgModule
decorator to node_modules/ng2-material-select/dist/src/ng2-select.module.d.ts
`import { NgModule } from '@angular/core';
@NgModule({ declarations: [ Ng2SelectModule ] }) export declare class Ng2SelectModule { }`
It works.
@lmsac did something get changed? Today webpack failed to compile because ERROR in Ng2SelectModule is not an NgModule
@playground I guess the reason is that there is something missing, such as metadata, required by the angular compiler. Finally I downloaded the source code of this project and add it to my app directly (not as a dependency). The source code was changed as following:
ng2-select.module.ts
import { NgModule } from '@angular/core';
import { Ng2Select } from './ng2-select';
import { ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { Ng2DropdownModule } from 'ng2-material-dropdown';
@NgModule({
imports: [
CommonModule,
ReactiveFormsModule,
Ng2DropdownModule
],
declarations: [
Ng2Select
],
exports: [
Ng2Select
]
})
export class Ng2SelectModule {}
ng2-select.ts
import {
Component,
Input,
Output,
forwardRef,
EventEmitter,
ViewChild,
ViewEncapsulation
} from '@angular/core';
import { Selectable } from './decorators/selectable';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { Ng2Dropdown } from 'ng2-material-dropdown';
import { DropdownStateService } from 'ng2-material-dropdown/dist/src/modules/services/dropdown-state.service';
import { SelectAccessor } from './accessor';
import { equal } from '../equals/equals';
const CUSTOM_SELECT_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => Ng2Select),
multi: true
};
/**
* A component for entering a list of terms to be used with ngModel.
*/
@Component({
selector: 'ng2-select',
providers: [CUSTOM_SELECT_VALUE_ACCESSOR],
styleUrls: ['./style.scss'],
templateUrl: './template.html',
encapsulation: ViewEncapsulation.None
})
@Selectable()
export class Ng2Select extends SelectAccessor {
@Input() public placeholder: string;
@Input() public options: any[] = [];
@Input() public displayBy: string;
@Input() public selectedDisplayBy: string;
@Input() public identifyBy: string;
@Input() public multiple: boolean = false;
@Output() public onChange: EventEmitter<string> = new EventEmitter<string>();
@ViewChild(Ng2Dropdown) public dropdown;
public getSelectedValue(): any {
if (this.multiple && this.value.length === 1) {
return this.selectedDisplayValue(this.value[0]);
} else {
const index = this.options.findIndex(item => equal(this.value, item));
return index >= 0 ? this.selectedDisplayValue(this.options[index]) : undefined;
}
}
public selectedDisplayValue(item): string {
return this.selectedDisplayBy ? item[this.selectedDisplayBy] : this.displayValue(item);
}
public displayValue(item): string {
return this.displayBy ? item[this.displayBy] : item;
}
public get placeholderDisplay(): string {
if (this.multiple && this.value.length > 1) {
return `${this.value.length} items selected`;
} else {
return this.getSelectedValue() || this.placeholder;
}
}
public isEqual(itemOne, itemTwo) {
return this.identifyBy ? itemOne[this.identifyBy] === itemTwo[this.identifyBy] :
equal(itemOne, itemTwo);
}
public isSelected(item): boolean {
if (this.multiple) {
return this.value.filter(value => this.isEqual(item, value)).length > 0;
} else {
return equal(this.value, item);
}
}
ngOnInit() {
const state = (<DropdownStateService>this.dropdown.state).dropdownState;
state.onItemClicked.subscribe(item => {
if (this.multiple) {
this.toggle(item.value);
} else {
this.value = this.multiple ? this.value : item.value;
}
this.onChange.emit(this.value);
});
this.dropdown.onShow.subscribe(() => {
if (!this.value) {
return;
}
// focus selected element
const index = this.findIndexValue(this.value);
const item = this.dropdown.menu.items.toArray()[index];
(<DropdownStateService>this.dropdown.state).dropdownState.select(item, false);
});
}
}
Ng2Select
depends on ng2-material-dropdown
, so add it by npm install
.
ng2-material-dropdown ^0.7.3
In Ng2Select
, this.dropdown.state
should be changed to (<DropdownStateService>this.dropdown.state).dropdownState
, maybe because of api changes of ng2-material-dropdown
.
ng2-material-material' depends on
equals, and
equalsdepends on
jkroso-type. The angular compiler doesn't support
require` function, so I downloaded source code of these two package, and changed them in typescript.
equals.ts
import { type } from '../jkroso-type/jkroso-type';
var types: any = {}
// (Number) -> boolean
types.number = function (a, b) {
return a !== a && b !== b/*Nan check*/
}
// (function, function, array) -> boolean
types['function'] = function (a, b, memos) {
return a.toString() === b.toString()
// Functions can act as objects
&& types.object(a, b, memos)
&& equal(a.prototype, b.prototype)
}
// (date, date) -> boolean
types.date = function (a, b) {
return +a === +b
}
// (regexp, regexp) -> boolean
types.regexp = function (a, b) {
return a.toString() === b.toString()
}
// (DOMElement, DOMElement) -> boolean
types.element = function (a, b) {
return a.outerHTML === b.outerHTML
}
// (textnode, textnode) -> boolean
types.textnode = function (a, b) {
return a.textContent === b.textContent
}
// decorate `fn` to prevent it re-checking objects
// (function) -> function
function memoGaurd(fn) {
return function (a, b, memos) {
if (!memos) return fn(a, b, [])
var i = memos.length, memo
while (memo = memos[--i]) {
if (memo[0] === a && memo[1] === b) return true
}
return fn(a, b, memos)
}
}
types['arguments'] =
types['bit-array'] =
types.array = memoGaurd(arrayEqual)
// (array, array, array) -> boolean
function arrayEqual(a, b, memos) {
var i = a.length
if (i !== b.length) return false
memos.push([a, b])
while (i--) {
if (!equal(a[i], b[i], memos)) return false
}
return true
}
types.object = memoGaurd(objectEqual)
// (object, object, array) -> boolean
function objectEqual(a, b, memos) {
if (typeof a.equal == 'function') {
memos.push([a, b])
return a.equal(b, memos)
}
var ka = getEnumerableProperties(a)
var kb = getEnumerableProperties(b)
var i = ka.length
// same number of properties
if (i !== kb.length) return false
// although not necessarily the same order
ka.sort()
kb.sort()
// cheap key test
while (i--) if (ka[i] !== kb[i]) return false
// remember
memos.push([a, b])
// iterate again this time doing a thorough check
i = ka.length
while (i--) {
var key = ka[i]
if (!equal(a[key], b[key], memos)) return false
}
return true
}
// (object) -> array
function getEnumerableProperties(object) {
var result = []
for (var k in object) if (k !== 'constructor') {
result.push(k)
}
return result
}
export function equal(a: any, b: any, memos?: any[]): boolean {
// All identical values are equivalent
if (a === b) return true
var fnA = types[type(a)]
var fnB = types[type(b)]
return fnA && fnA === fnB
? fnA(a, b, memos)
: false
}
jkroso-type.ts
var toString = {}.toString
/**
* Return the type of `val`.
*
* @param {Mixed} val
* @return {String}
* @api public
*/
export function type(x) {
var type = typeof x
if (type != 'object') return type
type = types[toString.call(x)]
if (type == 'object') {
// in case they have been polyfilled
if (x instanceof Map) return 'map'
if (x instanceof Set) return 'set'
return 'object'
}
if (type) return type
if (x instanceof Node) switch (x.nodeType) {
case 1: return 'element'
case 3: return 'text-node'
case 9: return 'document'
case 11: return 'document-fragment'
default: return 'dom-node'
}
}
export var types = {
'[object Function]': 'function',
'[object Date]': 'date',
'[object RegExp]': 'regexp',
'[object Arguments]': 'arguments',
'[object Array]': 'array',
'[object Set]': 'set',
'[object String]': 'string',
'[object Null]': 'null',
'[object Undefined]': 'undefined',
'[object Number]': 'number',
'[object Boolean]': 'boolean',
'[object Object]': 'object',
'[object Map]': 'map',
'[object Text]': 'text-node',
'[object Uint8Array]': 'bit-array',
'[object Uint16Array]': 'bit-array',
'[object Uint32Array]': 'bit-array',
'[object Uint8ClampedArray]': 'bit-array',
'[object Error]': 'error',
'[object FormData]': 'form-data',
'[object File]': 'file',
'[object Blob]': 'blob'
}
Finally, change app.module.ts
import { Ng2SelectModule } from '../vendor/ng2-material-select/ng2-select.module';
...
@NgModule({
imports: [
...
Ng2SelectModule
],
...
bootstrap: [AppComponent]
})
export class AppModule { }
It works with ng build
and ng build --prod
. ng build
uses webpack, so perhaps my solution is helpful to your issue.
This module is not compatible with default compiler that implements AOT. So it's a broken component as its missing its *.metadata.json file.
@Cogitaria for immediate/temporary fix as suggested by @lmsac
I have solved it by adding @NgModule decorator to node_modules/ng2-material-select/dist/src/ng2-select.module.d.ts
`import { NgModule } from '@angular/core';
@NgModule({ declarations: [ Ng2SelectModule ] }) export declare class Ng2SelectModule { }`
@Gbuomprisco do you intend on fixing this and the other modules you created that are no longer valid modules? Otherwise, honestly, you should delete these repos and remove it (from being listed, which is easy to do). If somebody stumbles on it they may make the mistake of thinking it a) works, b) might be actively maintained. Neither of course is true (see above comments about responsibility, which are spot on).
Playground, thanks, but our automated build has no room for doctoring what are essentially binaries as a post-install job. I'm going to look for an active component that meets the basic Angular requirements for a valid component.
Hi @Cogitaria,
yes - I will. When? I don't know - hopefully in the weekend, as my other modules are in good shape instead.
I don't agree with removing them, because:
- I certainly don't advertise my repos. This is also a showcase of work, not a marketplace.
- I spent time writing it, I would feel bad removing it
- It's very, very easy to spot if a package is maintained, up to users to check it out
This should be hopefully solve with the latest version
@Gbuomprisco Has this been fixed?