stencil-community / stencil-router

A simple router for Stencil apps and sites
https://stenciljs.com/
MIT License
187 stars 55 forks source link

this.history is undefined with injectHistory #79

Open sshrshnv opened 5 years ago

sshrshnv commented 5 years ago

Resources: https://stenciljs.com/docs/router-tutorials#inject-history-into-a-deep-component

Stencil version::

@stencil/core@0.15.2

I'm submitting a ... [x] bug report [ ] feature request [ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or https://stencil-worldwide.slack.com

Current behavior: this.history is undefined in a deep component

Expected behavior: this.history is not undefined

Steps to reproduce: All steps from https://stenciljs.com/docs/router-tutorials#inject-history-into-a-deep-component

sshrshnv commented 5 years ago

@jthoms1, the demo https://github.com/ionic-team/stencil-router/tree/master/packages/demo (test-deep-component) doesn't work too (this.history is undefined)

MoAsmar commented 5 years ago

Hi I am facing a similar issue, I tried to solve it by adding a default route with stencil-router-redirect as a fallback, in my case, I have a base url "myhost/app" and I want to redirect to "myhost/app/hello" on will load of the main app route which is "myhost/app", I tried to add InjectHistory to the same component that has the routes defined, but the history was undefined, so I tried to define a basic route with redirect like the below, even though it didn't work, the debugger did not enter the stencil-route

  <stencil-router root='/'>
   {/* Base Route >> redirect to first route */}
            <stencil-route url='/' routeRender={() => {
              return <stencil-router-redirect url={'/hello'} />;
            }} exact={true} />
           <stencil-route url='/hello' routeRender={() => {
              return <hello-component />;
            }} exact={true} />
    </stencil-router>
val-o commented 5 years ago

image Tried to debug this issue and found that function that creates Provider is copied in bundle 2 times, hence we have two copies of listeners and states in runtime, and notifyListeners never get called on custom components which we decorate with injectHitory.... I remember having same issue with multiple declaration of same class/function, unfortunately I didn't find a solution that time so we just came up with some hacky one...

val-o commented 5 years ago

Got it work by create fork with module: /collection in package.json, getting build warn though. Now injection seems to be working fine

genadis commented 5 years ago

It worked up to version 0.2.5, from version 0.2.6 stopped working. Are there any updates regarding the issue? Thanks!

numerized commented 5 years ago

Hi guys, impossible to use RouterHistory even with injectHistory from a deepComponent

carbonfish commented 4 years ago

Still not working

obrunopolo commented 4 years ago

Same issue here. I recently started an Ionic/Stencil starting from Ionic PWA Toolkit and I'm facing high dificulty to implement navigation. I did solve by changing app-root <ion-router> || <stencil-router> structure to simple <ion-nav root="app-home" /> and using document.querySelector('ion-nav').push(component_tag)

FabianEbert commented 4 years ago

I could not reproduce the issue on my side with stencil-router 1.0.1.

I needed to navigate programmatically in some component of my application which is not rendered by a stencil-route and followed this wiki article. To have the history() property defined, you need to additionally inject the history, the wiki article was not complete here.

So my full components looks like this now:

import { RouterHistory, injectHistory } from '@stencil/router'; // version 1.0.1

export class MyComponent {
  @Prop() history: RouterHistory;

  @Listen('my-custom-event')
  handleMyCustomEvent(event: CustomEvent) {
    this.history.push(event.detail.route, {});
  }
}

injectHistory(MyComponent);
green3g commented 3 years ago

I'm still running into this issue - even with @FabianEbert 's solution. I'm using a simple component like:

import { Component, h, Prop } from '@stencil/core';
import { injectHistory, RouterHistory } from '@stencil/router';

@Component({
    tag: 'app-navbar',
    styleUrl: 'app-navbar.css'
})
export class AppNavbar {

    @Prop() isActive: boolean;
    @Prop() authentication: any;
    @Prop() history: RouterHistory;

    render() {
        return (
            <p>{this.history.location.pathname}</p>
        );
    }
}

// injectHistor
injectHistory(AppNavbar);

And I'm receiving this error:

index-8cb312c3.js:2688 TypeError: Cannot read property 'location' of undefined
    at AppNavbar.render (app-navbar.entry.js:14)
    at callRender (index-8cb312c3.js:1408)
    at updateComponent (index-8cb312c3.js:1341)
    at index-8cb312c3.js:1317
    at then (index-8cb312c3.js:1540)
    at dispatchHooks (index-8cb312c3.js:1317)
    at Array.dispatch (index-8cb312c3.js:1285)
    at consume (index-8cb312c3.js:2733)
    at flush (index-8cb312c3.js:2786)