Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERROR in No NgModule metadata found for 'AppModule' #35143

Closed
2 of 15 tasks
TriumphTruth opened this issue Jan 19, 2020 · 21 comments
Closed
2 of 15 tasks

ERROR in No NgModule metadata found for 'AppModule' #35143

TriumphTruth opened this issue Jan 19, 2020 · 21 comments
Labels
area: compiler Issues related to `ngc`, Angular's template compiler freq1: low P5 The team acknowledges the request but does not plan to address it, it remains open for discussion state: confirmed type: bug/fix
Milestone

Comments

@TriumphTruth
Copy link

TriumphTruth commented Jan 19, 2020

馃悶 Bug report

Command

  • new
  • build
  • serve
  • test
  • e2e
  • generate
  • add
  • update
  • lint
  • xi18n
  • run
  • config
  • help
  • version
  • doc

Is this a regression?

It started happening in the same version without any version upgrade of any sort.

Description

There are 2 parts of the BUG. 1 during serve and 1 during build creation.

Description During Serve

If I need to tell this clearly, it can only be said that this bug occurred while doing development, And no changes to AppModule was made during that time. You hit npm start and you get the following error:
ERROR in No NgModule metadata found for 'AppModule'.

You save any file again and it will start compiling again and compile successfully.

Description during build

It runs the build and fails with the following error:
ERROR in members.hasOwnProperty is not a function

馃敩 Minimal Reproduction

I don't know how to reproduce it. It has occurred during development and without any upgrade to any packages.

馃敟 Exception or Error

Exception on SERVE:

No exception can be found except for the above error as told in the description.

Exception on BUILD:

No exception could be found except for the above error. But I will still put some details here:


0 info it worked if it ends with ok
1 verbose cli [
1 verbose cli   'C:\\Program Files\\nodejs\\node.exe',
1 verbose cli   'C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js',
1 verbose cli   'run',
1 verbose cli   'build'
1 verbose cli ]
2 info using npm@6.12.1
3 info using node@v12.13.1
4 verbose run-script [ 'prebuild', 'build', 'postbuild' ]
5 info lifecycle xxxx-ers@1.0.0~prebuild: xxxx-ers@1.0.0
6 info lifecycle xxxx-ers@1.0.0~build: xxxx-ers@1.0.0
7 verbose lifecycle xxxx-ers@1.0.0~build: unsafe-perm in lifecycle true
8 verbose lifecycle xxxx-ers@1.0.0~build: PATH: ...
9 verbose lifecycle xxxx-ers@1.0.0~build: CWD: C:\Projects\ERS\Repositories\xxxx.ERS.UI
10 silly lifecycle xxxx-ers@1.0.0~build: Args: [ '/d /s /c', 'npm run env -s && ng build --prod' ]
11 silly lifecycle xxxx-ers@1.0.0~build: Returned: code: 1  signal: null
12 info lifecycle xxxx-ers@1.0.0~build: Failed to exec build script
13 verbose stack Error: xxxx-ers@1.0.0 build: `npm run env -s && ng build --prod`
13 verbose stack Exit status 1
13 verbose stack     at EventEmitter. (C:\Program Files\nodejs\node_modules\npm\node_modules\npm-lifecycle\index.js:332:16)
13 verbose stack     at EventEmitter.emit (events.js:210:5)
13 verbose stack     at ChildProcess. (C:\Program Files\nodejs\node_modules\npm\node_modules\npm-lifecycle\lib\spawn.js:55:14)
13 verbose stack     at ChildProcess.emit (events.js:210:5)
13 verbose stack     at maybeClose (internal/child_process.js:1021:16)
13 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:283:5)
14 verbose pkgid xxxx-ers@1.0.0
15 verbose cwd C:\Projects\ERS\Repositories\xxxx.ERS.UI
16 verbose Windows_NT 10.0.17134
17 verbose argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "run" "build"
18 verbose node v12.13.1
19 verbose npm  v6.12.1
20 error code ELIFECYCLE
21 error errno 1
22 error xxxx-ers@1.0.0 build: `npm run env -s && ng build --prod`
22 error Exit status 1
23 error Failed at the xxxx-ers@1.0.0 build script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]

馃實 Your Environment


Angular CLI: 8.3.22
Node: 12.13.1
OS: win32 x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... platform-server, router, service-worker

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.800.6
@angular-devkit/build-angular      0.800.6
@angular-devkit/build-optimizer    0.800.6
@angular-devkit/build-webpack      0.800.6
@angular-devkit/core               8.0.6
@angular-devkit/schematics         8.3.22
@angular/cdk                       8.2.3
@angular/cli                       8.3.22
@angular/material                  8.2.3
@angular/material-moment-adapter   8.2.3
@ngtools/webpack                   8.0.6
@schematics/angular                8.3.22
@schematics/update                 0.803.22
rxjs                               6.5.4
typescript                         3.4.5
webpack                            4.30.0

Anything else relevant?
I have performed almost all the work arounds I found in the issues earlier reported but none of them worked. Like, adding the AppModule to tsconfig.app.json. Making sure const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule); is in the one line in main.ts. and host of other steps. But none of them works. Please help.

My main.ts


/*
 * Entry point of the application.
 * Only platform bootstrapping code should be here.
 * For app-specific initialization, use `app/app.component.ts`.
 */

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from '@app/app.module';
import { environment } from '@env/environment';
import { hmrBootstrap } from './hmr';

if (environment.production) {
  enableProdMode();
}

const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule);

if (environment.hmr) {
  hmrBootstrap(module, bootstrap);
} else {
  bootstrap().catch(err => console.error(err));
}

My App.module.ts


// Angular
import { BrowserModule, HAMMER_GESTURE_CONFIG } from '@angular/platform-browser';
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { TranslateModule } from '@ngx-translate/core';
import { HttpClientModule } from '@angular/common/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { GestureConfig, MatProgressSpinnerModule } from '@angular/material';
import { OverlayModule } from '@angular/cdk/overlay';
// Perfect Scroll bar
import { PERFECT_SCROLLBAR_CONFIG, PerfectScrollbarConfigInterface } from 'ngx-perfect-scrollbar';
// SVG inline
import { InlineSVGModule } from 'ng-inline-svg';
// Env
import { environment } from '@env/environment';
// Hammer JS
import 'hammerjs';
// Copmponents
import { AppComponent } from './app.component';
// Modules
import { AppRoutingModule } from './app-routing.module';
import { CoreModule } from './core/core.module';
import { ThemeModule } from './views/theme/theme.module';
// Partials
import { PartialsModule } from './views/partials/partials.module';
// Layout Services
import {
  //DataTableService,
  //FakeApiService,
  KtDialogService,
  LayoutConfigService,
  LayoutRefService,
  MenuAsideService,
  MenuConfigService,
  MenuHorizontalService,
  PageConfigService,
  SplashScreenService,
  SubheaderService
} from './core/_base/layout';
// CRUD
import { LayoutUtilsService, TypesUtilsService } from './core/_base/crud';
// Config
import { LayoutConfig } from './core/_config/layout.config';
// Highlight JS
import { HIGHLIGHT_OPTIONS, HighlightLanguage } from 'ngx-highlightjs';
import * as typescript from 'highlight.js/lib/languages/typescript';
import * as scss from 'highlight.js/lib/languages/scss';
import * as xml from 'highlight.js/lib/languages/xml';
import * as json from 'highlight.js/lib/languages/json';

// tslint:disable-next-line:class-name
const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
  wheelSpeed: 0.5,
  swipeEasing: true,
  minScrollbarLength: 40,
  maxScrollbarLength: 300
};

export function initializeLayoutConfig(appConfig: LayoutConfigService) {
  // initialize app by loading default demo layout config
  return () => {
    if (appConfig.getConfig() === null) {
      appConfig.loadConfigs(new LayoutConfig().configs);
    }
  };
}

export function hljsLanguages(): HighlightLanguage[] {
  return [
    { name: 'typescript', func: typescript },
    { name: 'scss', func: scss },
    { name: 'xml', func: xml },
    { name: 'json', func: json }
  ];
}

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserAnimationsModule,
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    // environment.isMockEnabled
    //   ? HttpClientInMemoryWebApiModule.forRoot(FakeApiService, {
    //       passThruUnknownUrl: true,
    //       dataEncapsulation: false
    //     })
    //   : [],
    //NgxPermissionsModule.forRoot(),
    PartialsModule,
    CoreModule,
    OverlayModule,
    //AuthModule,
    TranslateModule.forRoot(),
    MatProgressSpinnerModule,
    InlineSVGModule.forRoot(),
    ThemeModule
  ],
  exports: [],
  providers: [
    LayoutConfigService,
    LayoutRefService,
    MenuConfigService,
    PageConfigService,
    KtDialogService,
    //DataTableService,
    SplashScreenService,
    {
      provide: PERFECT_SCROLLBAR_CONFIG,
      useValue: DEFAULT_PERFECT_SCROLLBAR_CONFIG
    },
    {
      provide: HAMMER_GESTURE_CONFIG,
      useClass: GestureConfig
    },
    {
      // layout config initializer
      provide: APP_INITIALIZER,
      useFactory: initializeLayoutConfig,
      deps: [LayoutConfigService],
      multi: true
    },
    {
      provide: HIGHLIGHT_OPTIONS,
      useValue: { languages: hljsLanguages }
    },
    // template services
    SubheaderService,
    MenuHorizontalService,
    MenuAsideService,
    //HttpUtilsService,
    TypesUtilsService,
    LayoutUtilsService
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

My app-routing.module.ts


// Angular
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
// Components
import { BaseComponent } from './views/theme/base/base.component';
import { ErrorPageComponent } from './views/theme/content/error-page/error-page.component';
// Auth
import { AuthGuard } from './core/auth';
import { AuthenticationGuard  } from "@app/core";

const routes: Routes = [
  { path: 'auth', loadChildren: () => import('../app/views/pages/auth/auth.module').then(m => m.AuthModule) },

  {
    path: '',
    component: BaseComponent,
    canActivate: [AuthenticationGuard],
    children: [
      {
        path: 'dashboard',
        loadChildren: () => import('../app/views/pages/dashboard/dashboard.module').then(m => m.DashboardModule)
      },
      {
        path: 'kiosk',
        loadChildren: () => import('../app/views/pages/kiosk/kiosk.module').then(m => m.KioskModule)
      },
      {
        path: 'registration',
        loadChildren: () =>
          import('../app/views/pages/registeration/registeration.module').then(c => c.RegisterationModule)
      },
      {
        path: 'error/403',
        component: ErrorPageComponent,
        data: {
          type: 'error-v6',
          code: 403,
          title: '403... Access forbidden',
          desc: "Looks like you don't have permission to access for requested page.
Please, contact administrator" } }, { path: 'error/:type', component: ErrorPageComponent }, { path: '', redirectTo: 'dashboard', pathMatch: 'full' }, { path: '**', redirectTo: 'dashboard', pathMatch: 'full' } ] }, { path: '**', redirectTo: 'error/403', pathMatch: 'full' } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule {}
@TriumphTruth TriumphTruth changed the title ERROR in members.hasOwnProperty is not a function ERROR in No NgModule metadata found for 'AppModule' Jan 19, 2020
@alan-agius4
Copy link
Contributor

Hi, can you try to update @angular-devkit/build-angular to the latest version? The version in your project a couple of months old and since then a lot of issue has been addressed.

@TriumphTruth
Copy link
Author

Thanks @alan-agius4 I will surely do that in a few hours and let you all know the outcome.

@TriumphTruth
Copy link
Author

No @alan-agius4 same issue.

@umutyerebakmaz
Copy link

everything is up to date I have the same problem.

main.ts

  import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

import 'hammerjs';

if (environment.production) {
  enableProdMode();
}

document.addEventListener('DOMContentLoaded', () => {
  platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err));
});

package.json

  "devDependencies": {
    "@angular-devkit/build-angular": "0.803.23",
    "@angular/cli": "8.3.23",
    "@angular/compiler-cli": "8.2.14",
    "@angular/language-service": "8.2.14",
    "@types/jasmine": "3.5.0",
    "@types/jasminewd2": "2.0.8",
    "@types/moment": "2.13.0",
    "@types/node": "12.12.24",
    "codelyzer": "5.2.1",
    "concurrently": "5.0.2",
    "jasmine-core": "3.5.0",
    "jasmine-spec-reporter": "4.2.1",
    "karma": "4.4.1",
    "karma-chrome-launcher": "3.1.0",
    "karma-coverage-istanbul-reporter": "2.1.1",
    "karma-jasmine": "3.1.0",
    "karma-jasmine-html-reporter": "1.5.1",
    "protractor": "5.4.2",
    "ts-loader": "6.2.1",
    "ts-node": "8.6.2",
    "tslint": "5.20.1",
    "typescript": "3.5.3",
    "webpack-cli": "3.3.10"
  }

@umutyerebakmaz
Copy link

it's my mistakes. work for me sorry.

@alan-agius4
Copy link
Contributor

Closed as it seem the user solved the issue.

@TriumphTruth
Copy link
Author

@alan-agius4 I haven't solved the issue and need you guys input. I don't know why you closed the issue assuming something I never posted. Please reopen the issue.

@alan-agius4
Copy link
Contributor

@TriumphTruth sorry got confused by the other comment.

@alan-agius4 alan-agius4 reopened this Jan 21, 2020
@filipesilva
Copy link
Contributor

Heya, regarding the weird behaviour during ng serve where you got an error, then saved and the error was gone, I have seen this before and it's a bug we had (or maybe still have on 9) where rebuilds didn't identify some types of errors properly.

The error during ng build is the "real" error in your application though. That's the one you should focus on reproducing.

I don't think we can help much with the details in your original issue since that's not code we can copy over to reproduce the error. My suggestion would be start removing parts of your code and take it down to the minimal example that still shows the error, then putting that on a github repository and sharing it here.

I know this sounds like a lot of work but it's still the best way of getting some help in open source. If you provide a reproduction anyone can look at it and try to fix the actual problem. But without a reproduction everyone is just guessing and suggesting random things that might or might not have anything to do it with and it's just a waste of time for everyone involved.

@TriumphTruth
Copy link
Author

TriumphTruth commented Jan 23, 2020

@filipesilva I will try to do this tonight and get back to the community. Thanks for the guidance. Actually I have got to a point where I am worried about removal.... resulting in further deterioration of the project....... Nevermind, I think there is nothing else left to loose. So lets see. Will update here what happens.

@TriumphTruth
Copy link
Author

Update

I have been able to isolate the ng serve issue. But don't quite understand why that is the case.

If app.module.ts contains the reference of my TypesUtilsService, I get the Error in No NgModule metadata found for 'App Module'

TypesUtilsService class:


/** Angular */
import { Injectable } from '@angular/core';
import * as _ from 'lodash';

@Injectable()
export class TypesUtilsService {

  constructor(){
    
  }
  
  /**
   * Convert number to string and addinng '0' before
   *
   * @param value: number
   */
  padNumber(value: number) {
    if (this.isNumber(value)) {
      return `0${value}`.slice(-2);
    } else {
      return '';
    }
  }

  /**
   * Covert value to number
   *
   * @param value: any
   */
  toInteger(value: any): number {
    return parseInt(`${value}`, 10);
  }

  /**
   * Convert date to string with 'MM/dd/yyyy' format
   *
   * @param date: Date
   */
  dateFormat(date: Date): string {
    const month = date.getMonth() + 1;
    const day = date.getDate();
    const year = date.getFullYear();
    if (date) {
      return `${month}/${day}/${year}`;
    }

    return '';
  }

  /**
   * Convert Date to string with custom format 'MM/dd/yyyy'
   *
   * @param date: any
   */
  dateCustomFormat(date: any): string {
    let stringDate = '';
    if (date) {
      stringDate += this.isNumber(date.month) ? this.padNumber(date.month) + '/' : '';
      stringDate += this.isNumber(date.day) ? this.padNumber(date.day) + '/' : '';

      stringDate += date.year;
    }
    return stringDate;
  }

  /**
   * Convert string to DateFormatter (For Reactive Forms Validators)
   *
   * @param dateInStr: string (format => 'MM/dd/yyyy')
   */
  getDateFormatterFromString(dateInStr: string): any {
    if (dateInStr && dateInStr.length > 0) {
      const dateParts = dateInStr.trim().split('/');
      return [
        {
          year: this.toInteger(dateParts[2]),
          month: this.toInteger(dateParts[0]),
          day: this.toInteger(dateParts[1])
        }
      ];
    }

    const _date = new Date();
    return [
      {
        year: _date.getFullYear(),
        month: _date.getMonth() + 1,
        day: _date.getDay()
      }
    ];
  }

  /**
   * Convert string to Date
   *
   * @param dateInStr: string (format => 'MM/dd/yyyy')
   */
  getDateFromString(dateInStr: string = ''): Date {
    if (dateInStr && dateInStr.length > 0) {
      const dateParts = dateInStr.trim().split('/');
      const year = this.toInteger(dateParts[2]);
      const month = this.toInteger(dateParts[0]);
      const day = this.toInteger(dateParts[1]);
      // tslint:disable-next-line:prefer-const
      let result = new Date();
      result.setDate(day);
      result.setMonth(month - 1);
      result.setFullYear(year);
      return result;
    }

    return new Date();
  }

  /**
   * Convert Date to string with format 'MM/dd/yyyy'
   * @param _date: Date?
   */
  getDateStringFromDate(_date: Date = new Date()): string {
    const month = _date.getMonth() + 1;
    const year = _date.getFullYear();
    const date = _date.getDate();
    return `${month}/${date}/${year}`;
  }

  isNull(o: any) {
    return o === null;
  }

  isDesktop() {
    if (innerWidth > 980) {
      return true;
    } else {
      return false;
    }
  }

  isTablet() {
    if (innerWidth >= 768 && innerWidth < 980) {
      return true;
    } else {
      return false;
    }
  }

  isMobile() {
    if (innerWidth < 768) {
      return true;
    } else {
      return false;
    }
  }

  isObject(o: any) {
    if (this.isDefined(o)) return typeof o === 'object';
    return false;
  }

  isZero(o: any) {
    if (this.isDefined(o)) {
      if (typeof o === 'number' || typeof o === 'string') {
        return o === 0 || o === '0';
      }
    }
    return false;
  }

  isEmpty(value: any) {
    if (this.isDefined(value)) {
      if (typeof value === 'string') {
        return value === '';
      }
    }

    return false;
  }

  camelCase(o: any) {
    if (this.isStringWithLength(o)) {
      return o
        .replace(/\s(.)/g, function($1: any) {
          return $1.toUpperCase();
        })
        .replace(/\s/g, '')
        .replace(/^(.)/, function($1: any) {
          return $1.toLowerCase();
        });
    }
    return o;
  }
  isDefined(o: any) {
    return !this.isNullOrUndefined(o);
  }

  isUndefined(o: any) {
    return o === undefined;
  }

  isNullOrUndefined(o: any) {
    return this.isNull(o) || this.isUndefined(o);
  }

  isUndefinedOrNull(o: any) {
    return this.isNullOrUndefined(o);
  }

  isFunction(f: any) {
    return this.isDefined(f) && typeof f === 'function';
  }

  isArray(o: any) {
    return this.isDefined(o) && Array.isArray(o);
  }

  isString(o: any) {
    return this.isDefined(o) && typeof o === 'string';
  }

  isArrayWithLength(o: any) {
    return this.isArray(o) && o.length > 0;
  }

  isNumeric(o: any) {
    return !isNaN(parseFloat(o)) && isFinite(o);
  }

  isNumber(value: any) {
    return this.isNumeric(value);
  }

  isTrue(o: any) {
    return this.isDefined(o) && typeof o === 'boolean' && o === true;
  }

  isFalse(o: any) {
    return this.isDefined(o) && typeof o === 'boolean' && o === false;
  }

  isBoolean(o: any) {
    return this.isTrue(o) || this.isFalse(o);
  }

  isStringWithLength(o: any) {
    return this.isString(o) && o.length > 0;
  }

  isIE() {
    if (
      !(
        navigator.userAgent.indexOf('Chrome') !== -1 ||
        navigator.userAgent.indexOf('Firefox') !== -1 ||
        navigator.userAgent.indexOf('Safari') !== -1
      )
    ) {
      return true;
    } else {
      return false;
    }
  }
  verifyBrowserEdge() {
    if (
      (navigator.userAgent.indexOf('Chrome') !== -1 || navigator.userAgent.indexOf('Firefox') !== -1) &&
      navigator.userAgent.indexOf('Edge') === -1
    ) {
      return true;
    } else {
      return false;
    }
  }
  isChrome() {
    if (navigator.userAgent.indexOf('Chrome') !== -1) {
      return true;
    } else {
      return false;
    }
  }
  isFirefox() {
    if (navigator.userAgent.indexOf('Firefox') !== -1) {
      return true;
    } else {
      return false;
    }
  }
  isEdge() {
    if (navigator.userAgent.indexOf('Edge') !== -1) {
      return true;
    } else {
      return false;
    }
  }
  isMac() {
    if (navigator.userAgent.indexOf('Mac') !== -1) {
      return true;
    } else {
      return false;
    }
  }

  formatString(value: any, optValueArgs: any) {
    if (this.isStringWithLength(value) && this.isObject(optValueArgs)) {
      _.each(optValueArgs, function(valueObj, key) {
        let templateKey = ['{{', key, '}}'].join('');
        value = value.replace(templateKey, valueObj);
      });
    }

    return value;
  }

  isDate(o: any) {
    if (this.isDefined(o)) return !isNaN(new Date(o).valueOf());

    return false;
  }

  isEmail(o: any) {
    let regExp = new RegExp('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$');

    return this.isString(o) && regExp.test(o);
  }

  navigateRoute(route: string, object: any) {
    let url = this.append(route);

    for (let key in object) {
      if (key) {
        if (key !== 'constructor') {
          url += this.append(object[key].toString());
        }
      }
    }

    if (this.isStringWithLength(url)) {
      url = this.remove(url);
    }

    return url;
  }

  append(obj: any, char: any = undefined) {
    if (this.isUndefined(char)) {
      char = '/';
    }
    if (this.isString(obj)) {
      if (obj.charAt(obj.length - 1) !== char) {
        obj = obj.concat(char);
      }
    }
    return obj;
  }

  remove(obj: any, char: any = undefined) {
    if (this.isUndefined(char)) {
      char = '/';
    }
    if (this.isString(obj)) {
      if (obj.charAt(obj.length - 1) === char) {
        obj = obj.substring(0, obj.length - 1);
      }
    }
    return obj;
  }

  hasOwnProperty(o: any, prop: any) {
    return this.isDefined(o) && this.isDefined(o[prop]);
  }

  init(obj: any, prop: any, value: any = undefined) {
    return this.hasOwnProperty(obj, prop) ? obj[prop] : value;
  }

  date() {
    return {
      add: function() {
        return {
          minutes: function(minutes: any) {
            let date = new Date();
            if (this.isNumeric(minutes)) {
              return new Date(date.getTime() + minutes * 60000);
            }
          }
        };
      }
    };
  }

  calculate() {
    return {
      age: function(dob: any) {
        if (this.isDefined(dob)) {
          if (dob instanceof Date) {
            let now = new Date(),
              year = now.getFullYear(),
              month = now.getMonth(),
              day = now.getDate(),
              age = year - dob.getFullYear();

            if (month < dob.getMonth() - 1) age--;
            if (dob.getMonth() - 1 === month && day < dob.getDay()) age--;

            return age;
          }
        }
        return undefined;
      }
    };
  }

  key() {
    let controlChar = [0, 8, 13],
      navigationChar = [35, 36, 37, 38, 39, 40];
    return {
      isNumber: (which: any) => {
        if (this.isDefined(which)) {
          return !this.key().isNotNumber(which);
        }
        return false;
      },
      isNavigation: (which: any) => {
        if (this.isDefined(which)) {
          return navigationChar.indexOf(which) !== -1;
        }
        return false;
      },
      isNotNumber: (which: any) => {
        if (this.isDefined(which)) {
          return which < 44 || which > 57 || which === 47;
        }
        return false;
      },
      isControlChar: (which: any) => {
        return controlChar.indexOf(which) !== -1;
      },
      isNotControlChar: (which: any) => {
        return controlChar.indexOf(which) === -1;
      },
      alpha: (value: any) => {
        return value === 32 || String.fromCharCode(value).match(/^[a-zA-Z]*$/);
      },
      isAlphaNumeric: (value: any) => {
        return value === 32 || value === 35 || String.fromCharCode(value).match(/^[a-zA-Z0-9_]*$/);
      }
    };
  }

  pluck() {
    return {
      phoneNumber: (value: any) => {
        return value.replace(/[^0-9]/g, '');
      },
      decimals: (value: any) => {
        return value.indexOf('.') === -1 ? '' : value.replace(/^-?\d+(?=\.)/, '');
      },
      cardinal: (value: any) => {
        return value.replace(/(\.\d+)$/, '');
      },
      number: (value: any) => {
        return value.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
      }
    };
  }

  // extend() {
  //   return {
  //     date: (d: Date) => {
  //       if (this.isDate(d)) {
  //         d['addHours'] = (h: any) => {
  //           this.setHours(this.getHours() + h);
  //           return this;
  //         };
  //       }
  //       return d;
  //     }
  //   };
  // }

  /**
   * Construct format
   * @param documents
   * @returns {string}
   */
  format() {
    return {
      queryString: function(items: Array, lhs: string = 'id', rhs: string = 'id') {
        let url: string = '';
        let expression: string = '&PROPERTY=N'.replace(/PROPERTY/g, lhs);

        if (this.isArrayWithLength(items)) {
          if (this.isStringWithLength(rhs)) {
            //
            // Loop through documents
            //
            _.each(items, item => {
              if (this.hasOwnProperty(item, rhs)) {
                url += expression.replace(/N/g, item[rhs]);
              }
            });
          }
        }
        //
        // Prefix Url with '?'
        //
        if (this.isStringWithLength(url)) {
          if (url[0] === '&') {
            url = url.substring(1);
            url = '?' + url;
          }
        }

        return url;
      }
    };
  }
}

It is basically just a helper function class. Can anybody make any sense of this? Build issue is still there. And removal of the reference from App.Module.TS does not cause build to succeed.

@TriumphTruth
Copy link
Author

Update

I was able to solve the build issue as well. But haven't been able to quite understand the what is causing the issue. After having been able to single out the problematic service; the TypesUtilsService. I removed most of the functions I had in this file, and for now kept the bare minimum which I am using and is also not interfering in the application build. Now the file looks like this:


/** Angular */
import { Injectable } from '@angular/core';
import _ from 'lodash';

@Injectable()
export class TypesUtilsService {
	/**
	 * Convert number to string and addinng '0' before
	 *
	 * @param value: number
	 */
	padNumber(value: number) {
		if (this.isNumber(value)) {
			return `0${value}`.slice(-2);
		} else {
			return '';
		}
	}

	/**
	 * Checking value type equals to Number
	 *
	 * @param value: any
	 */
	isNumber(value: any): boolean {
		return !isNaN(this.toInteger(value));
	}

	/**
	 * Covert value to number
	 *
	 * @param value: any
	 */
	toInteger(value: any): number {
		return parseInt(`${value}`, 10);
	}

	/**
	 * Convert date to string with 'MM/dd/yyyy' format
	 *
	 * @param date: Date
	 */
	dateFormat(date: Date): string {
		const month = date.getMonth() + 1;
		const day = date.getDate();
		const year = date.getFullYear();
		if (date) {
			return `${month}/${day}/${year}`;
		}

		return '';
	}

	/**
	 * Convert Date to string with custom format 'MM/dd/yyyy'
	 *
	 * @param date: any
	 */
	dateCustomFormat(date: any): string {
		let stringDate = '';
		if (date) {
			stringDate += this.isNumber(date.month) ? this.padNumber(date.month) + '/' : '';
   stringDate += this.isNumber(date.day) ? this.padNumber(date.day) + '/' : '';

			stringDate += date.year;
        }
  return stringDate;
	}

	/**
	 * Convert string to DateFormatter (For Reactive Forms Validators)
	 *
	 * @param dateInStr: string (format => 'MM/dd/yyyy')
	 */
	getDateFormatterFromString(dateInStr: string): any {
		if (dateInStr && dateInStr.length > 0) {
			const dateParts = dateInStr.trim().split('/');
			return [
				{
					year: this.toInteger(dateParts[2]),
					month: this.toInteger(dateParts[0]),
					day: this.toInteger(dateParts[1])
				}
			];
		}

		const _date = new Date();
		return [
			{
				year: _date.getFullYear(),
				month: _date.getMonth() + 1,
				day: _date.getDay()
			}
		];
	}

	/**
	 * Convert string to Date
	 *
	 * @param dateInStr: string (format => 'MM/dd/yyyy')
	 */
	getDateFromString(dateInStr: string = ''): Date {
		if (dateInStr && dateInStr.length > 0) {
			const dateParts = dateInStr.trim().split('/');
			const year = this.toInteger(dateParts[2]);
			const month = this.toInteger(dateParts[0]);
			const day = this.toInteger(dateParts[1]);
			// tslint:disable-next-line:prefer-const
			let result = new Date();
			result.setDate(day);
			result.setMonth(month - 1);
			result.setFullYear(year);
			return result;
		}

		return new Date();
	}


	/**
	 * Convert Date to string with format 'MM/dd/yyyy'
	 * @param _date: Date?
	 */
	getDateStringFromDate(_date: Date = new Date()): string {
		const month = _date.getMonth() + 1;
		const year = _date.getFullYear();
		const date = _date.getDate();
		return `${month}/${date}/${year}`;
  }

  isObject(o: any) {
    if (this.isDefined(o)) return typeof o === 'object';
    return false;
  }

  isDefined(o: any) {
    return !this.isNullOrUndefined(o);
  }

  isString(o: any) {
    return this.isDefined(o) && typeof o === 'string';
  }

  isStringWithLength(o: any) {
    return this.isString(o) && o.length > 0;
  }

  formatString(value: any, optValueArgs: any) {
    if (this.isStringWithLength(value) && this.isObject(optValueArgs)) {
      _.each(optValueArgs, function(valueObj, key) {
        let templateKey = ['{{', key, '}}'].join('');
        value = value.replace(templateKey, valueObj);
      });
    }

    return value;
  }
  
  isNullOrUndefined(o: any) {
    return this.isNull(o) || this.isUndefined(o);
  }

  isNull(o: any) {
    return o === null;
  }
  isUndefined(o: any) {
    return o === undefined;
  }
}

I am clueless about why it was causing an issue before. I am in the middle of some tight deadlines, if someone can research it out it will be better. Else I will update later on if I am able to pin point the function or property causing that irregular errors.

Hope this helps.

@filipesilva
Copy link
Contributor

Heya @TriumphTruth, thanks for the repro! I tried using the full service (the one in https://github.com/angular/angular-cli/issues/16706#issuecomment-578398531) in a new project with the latest 9.0.0 RC, and saw this error:

    
    ERROR in src/app/TypesUtilsService.ts:484:37 - error TS2314: Generic type 'Array<T>' requires 1 type argument(s).
    
    484       queryString: function (items: Array, lhs: string = 'id', rhs: string = 'id') {

I replaced it with items: Array<any> and it seemed to compile. This error makes sense so I think it is correct to fix it. I saw no error at runtime.

Then I also disabled the Ivy compiler (new apps have it enabled by default) and I saw this compilation error:

ERROR in members.hasOwnProperty is not a function
D:\sandbox\next-app\node_modules\@angular\compiler-cli\src\transformers\program.js:672
            throw e;
            ^

TypeError: members.hasOwnProperty is not a function
    at recordMember (D:\sandbox\next-app\node_modules\@angular\compiler-cli\src\metadata\collector.js:134:40)
    at classMetadataOf (D:\sandbox\next-app\node_modules\@angular\compiler-cli\src\metadata\collector.js:203:37)
    at D:\sandbox\next-app\node_modules\@angular\compiler-cli\src\metadata\collector.js:358:54
    at visitNodes (D:\sandbox\next-app\node_modules\typescript\lib\typescript.js:17774:30)
    at Object.forEachChild (D:\sandbox\next-app\node_modules\typescript\lib\typescript.js:18007:24)
    at MetadataCollector.getMetadata (D:\sandbox\next-app\node_modules\@angular\compiler-cli\src\metadata\collector.js:312:16)
    at MetadataCache.getMetadata (D:\sandbox\next-app\node_modules\@angular\compiler-cli\src\transformers\metadata_cache.js:87:41)
    at Object.getSourceFileMetadata (D:\sandbox\next-app\node_modules\@angular\compiler-cli\src\transformers\compiler_host.js:127:56)
    at Object.readMetadata (D:\sandbox\next-app\node_modules\@angular\compiler-cli\src\transformers\metadata_reader.js:46:37)
    at TsCompilerAotCompilerTypeCheckHostAdapter.getMetadataFor (D:\sandbox\next-app\node_modules\@angular\compiler-cli\src\transformers\compiler_host.js:498:38)

Also odd that I only saw this error when adding the file on a rebuild, I couldn't get the full stack trace on initial build.

I don't know what this error means, but it goes away when I use your reduced version of the file in https://github.com/angular/angular-cli/issues/16706#issuecomment-578406419.

This might be the cause of the problem you are seeing. But from the logs this looks like a compiler error. Will transfer it over to the main repository for investigation.

@filipesilva filipesilva transferred this issue from angular/angular-cli Feb 4, 2020
@alxhub
Copy link
Member

alxhub commented Feb 4, 2020

The issue is that your class defines a hasOwnProperty function.

The MetadataCollector in View Engine eventually produces a metadata object of the form:

{
  isObject: {...},
  isNull: {...},
  hasOwnProperty: {...},
  ...
}

with one metadata entry for each member of the class. Because this object has a hasOwnProperty key (matching the function in your class), it shadows the real Object.prototype.hasOwnProperty function, causing a crash.

The workaround is to not declare a member with the name hasOwnProperty.

@alxhub alxhub added severity2: inconvenient type: bug/fix area: compiler Issues related to `ngc`, Angular's template compiler freq1: low labels Feb 4, 2020
@ngbot ngbot bot modified the milestone: Backlog Feb 4, 2020
@TriumphTruth
Copy link
Author

Thank you for investigating this @filipesilva . It makes total sense of the error you mentioned. The problem I had was there was no mention of any error during the compilation. Feels good that version 9.0.0 is accounting and reporting the error correctly.

@TriumphTruth
Copy link
Author

@alxhub makes sense, I will make this change and work through my project.... But should there not be a reasonable stacktrace at least?

@alxhub
Copy link
Member

alxhub commented Feb 4, 2020

This isn't an "error" - you're allowed to have a member function named hasOwnProperty. It's a crash caused by a bug - something that wasn't anticipated in the design of the MetadataCollector. So the actual mechanism of the failure is unpredictable. I don't know why the error gets swallowed during regular invocation.

@TriumphTruth
Copy link
Author

Sounds reasonable. 馃憤

@TriumphTruth
Copy link
Author

Another observation is that in my previous project, I had been using the same methods as the following:

library.ts

.
.
.
.
export function hasOwnProperty(o: any, prop: any) {
  return isDefined(o) && isDefined(o[prop]);
}

export function init(obj: any, prop: any, value: any = undefined) {
  return hasOwnProperty(obj, prop) ? obj[prop] : value;
}
.
.
.
.

I never faced this issue in it. That project has the following configuration:

package.json

 "dependencies": {
    "@angular/animations": "^7.0.0",
    "@angular/common": "^7.0.0",
    "@angular/compiler": "^7.0.0",
    "@angular/core": "^7.0.0",
    "@angular/forms": "^7.0.0",
    "@angular/http": "^7.0.0",
    "@angular/platform-browser": "^7.0.0",
    "@angular/platform-browser-dynamic": "^7.0.0",
    "@angular/router": "^7.0.0",
    "@angular/service-worker": "^7.0.0",

I think it is because function itself is not a class and hence it proceeded with no errors? It never collected any metadata of itself except the arguments, I assume.

@jelbourn jelbourn added P4 A relatively minor issue that is not relevant to core functions and removed P4 A relatively minor issue that is not relevant to core functions labels Oct 1, 2020
@ngbot ngbot bot modified the milestones: Backlog, needsTriage Oct 1, 2020
@jelbourn jelbourn added the P5 The team acknowledges the request but does not plan to address it, it remains open for discussion label Oct 1, 2020
@ngbot ngbot bot modified the milestones: needsTriage, Backlog Oct 1, 2020
@JoostK
Copy link
Member

JoostK commented May 14, 2021

The Ivy compiler no longer has a metadata collector that was prone to unsupported syntax issues, so closing as resolved.

@JoostK JoostK closed this as completed May 14, 2021
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jun 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: compiler Issues related to `ngc`, Angular's template compiler freq1: low P5 The team acknowledges the request but does not plan to address it, it remains open for discussion state: confirmed type: bug/fix
Projects
None yet
Development

No branches or pull requests

7 participants