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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot read property 'insertBefore' of null #64

Open
EvanBurbidge opened this issue Jul 28, 2017 · 5 comments
Open

Cannot read property 'insertBefore' of null #64

EvanBurbidge opened this issue Jul 28, 2017 · 5 comments

Comments

@EvanBurbidge
Copy link

EvanBurbidge commented Jul 28, 2017

Looks like this is occurring in the createNewHosts function call.

function createNewHosts(cmps) {
    var components = cmps.map(function (componentNode) {
        var newNode = document.createElement(componentNode.tagName);
        // display none
        var currentDisplay = newNode.style.display;
        newNode.style.display = 'none';
        var parentNode = componentNode.parentNode;
        parentNode.insertBefore(newNode, componentNode); //Problem hits here

         //Potential fix simple but could avoid this in future. 
         if ( !!componentNode.parentNode ) {
              var parentNode = componentNode.parentNode;
              parentNode.insertBefore(newNode, componentNode);
         }

        return { currentDisplay: currentDisplay, newNode: newNode };
    });
@PatrickJS
Copy link
Owner

how are you using createNewHosts

@EvanBurbidge
Copy link
Author

EvanBurbidge commented Jul 31, 2017

Apologies for the delay was not at my computer all weekend.
Main.browser.ts

declare const ENV:any;

import './polyfills';
import './rxjs.imports';

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { bootloader } from '@angularclass/hmr';
import {decorateModuleRef} from "./env";
import {AppModule} from "./app/app.module";


if (ENV === 'production'){
    enableProdMode();
}

export function main():Promise<any> {
    return platformBrowserDynamic()
        .bootstrapModule(AppModule)
        .then(decorateModuleRef)
        .catch(err => console.log(err))
}

bootloader(main);

App.module.ts

import {NgModule, ApplicationRef} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser'
import { removeNgStyles, createNewHosts, createInputTransfer } from '@angularclass/hmr';
import { Store , StoreModule} from '@ngrx/store';
import {AppComponent} from './app.comp';
import {rootReducer} from './reducers';
import {counterReducer} from "./counter/counter.reducer";
import {CounterComponent} from "./counter/counter.component";

@NgModule({
    declarations: [AppComponent, CounterComponent],
    imports:[
        BrowserModule,
        StoreModule.provideStore(rootReducer)
    ],
    bootstrap:[AppComponent],
    exports:[]
})

export class AppModule {
    constructor(public appRef: ApplicationRef,
                private _store: Store<AppState>) {
    }

    hmrOnInit(store) {
        if (!store || !store.rootState) return;

        // restore state by dispatch a SET_ROOT_STATE action
        if (store.rootState) {
            this._store.dispatch({
                type: 'SET_ROOT_STATE',
                payload: store.rootState
            });
        }

        if ('restoreInputValues' in store) { store.restoreInputValues(); }
        this.appRef.tick();
        Object.keys(store).forEach(prop => delete store[prop]);
    }
    hmrOnDestroy(store) {
        const cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement);
        this._store.take(1).subscribe(s => store.rootState = s);
        store.disposeOldHosts = createNewHosts(cmpLocation);
        store.restoreInputValues = createInputTransfer();
        removeNgStyles();
    }
    hmrAfterDestroy(store) {
        store.disposeOldHosts();
        delete store.disposeOldHosts;
    }
};

export interface AppState {}

@Minh-Van
Copy link

Minh-Van commented Jun 2, 2018

I got same problem. Any update for this issue ?

@montella1507
Copy link

montella1507 commented Jun 12, 2018

Same here.

HMR.ts

import { NgModuleRef, ApplicationRef } from '@angular/core';
import { createNewHosts, hmrModule } from '@angularclass/hmr';

export const hmrBootstrap = (module: any, bootstrap: () => Promise<NgModuleRef<any>>) => {
    let ngModule: NgModuleRef<any>;
    module.hot.accept();
    bootstrap().then((mod) => {
        ngModule = mod;
        return hmrModule(mod, module); // this line is missing in Angular 6 HMR story
    });
    module.hot.dispose(() => {
        const appRef: ApplicationRef = ngModule.injector.get(ApplicationRef);
        const elements = appRef.components.map(c => c.location.nativeElement);
        const makeVisible = createNewHosts(elements);
        // ngModule.destroy(); - "has been already destroyed error - in NG6" 
        makeVisible();
    });
};

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 { hmrBootstrap } from './hmr';

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

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

if (environment.hmr) {
  if (module['hot']) {
    hmrBootstrap(module, bootstrap);
  } else {
    console.error('HMR is not enabled for webpack-dev-server!');
    console.log('Are you using the --hmr flag for ng serve?');
  }
} else {
  bootstrap();
}

app.module.ts

import { NgModule, ApplicationRef } from '@angular/core';
import { removeNgStyles, createNewHosts, bootloader, createInputTransfer } from '@angularclass/hmr';
import { AppComponent } from './app.component';
import { SharedModule } from '@shared/shared.module';
import { CoreModule } from '@core/core.module';
import { StoreModule, ActionReducer, Action, MetaReducer, Store } from '@ngrx/store';
import { testReducer } from '@shared/reducers/test.reducer';
import { take } from 'rxjs/operators';

// make sure you export for AoT
export function stateSetter(reducer: ActionReducer<any>): ActionReducer<any> {
  return function (state: any, action: any) {
    if (action.type === 'SET_ROOT_STATE') {
      console.log(action.payload);
      return action.payload;
    }
    return reducer(state, action);
  };
}


export const xyz: MetaReducer<{ count: any }, Action>[] = [stateSetter];

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    CoreModule,
    StoreModule.forRoot({ count: testReducer }, { metaReducers: xyz }),
    SharedModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {

  constructor(public appRef: ApplicationRef, private _store: Store<any>) { }


  hmrOnDestroy(store) {
    const cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement)
    this._store.pipe(take(1)).subscribe(s => store.rootState = s);
    store.disposeOldHosts = createNewHosts(cmpLocation);  // <<<<<<<<====== crash - insertBefore
    store.restoreInputValues = createInputTransfer();
    removeNgStyles();
  }

  hmrAfterDestroy(store) {
    store.disposeOldHosts();
    delete store.disposeOldHosts;
  }

  hmrOnInit(store) {
    if (!store || !store.rootState) {
      return;
    }

    // restore state by dispatch a SET_ROOT_STATE action
    if (store.rootState) {
      this._store.dispatch({
        type: 'SET_ROOT_STATE',
        payload: store.rootState
      });
    }

    if ('restoreInputValues' in store) { store.restoreInputValues(); }
    this.appRef.tick();
    Object.keys(store).forEach(prop => delete store[prop]);
  }
}

@montella1507
Copy link

The problem seems to be here in Helpers.js

var parentNode = componentNode.parentNode; <<< componentNode is "app-component" selector, parentNode is "NULL".. however.. parent node in DOM is
var currentDisplay = newNode.style.display;
newNode.style.display = 'none';
parentNode.insertBefore(newNode, componentNode);

maybe it is because of angular 6 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants