Skip to content

insidious problems not documented when using typescript the "this" instance is not mounted correctly in results callback #698

Open
@fvigotti

Description

@fvigotti

Hi,
I want to show an issue that bitten me hard in the past days, I've had problems in subscriptions but I've seen same behaviour in queries too ,

my current versions of vue-apollo are the latest one available today ("vue-apollo": "3.0.0-rc.1", ) ( aswell as latest version of nuxt/vue etc ) , but while investigating I've seen this issue existing in past versions too

wrong

    get apollo () {
      let instance = this as unknown as StatsDashboardPage // <<--- this instance variable will be wrong ( dont't have the mounted page components ) 
      return   { // this is called before local context being setup ( properties not available )
        $subscribe : {
          simplesub1: <VueApolloSubscriptionOptions<StatsDashboardPage, TrafficSummaryDashboardSubscription>>{
            query : trafficSummaryDashboard
            ,variables: <GQLtypes.TrafficSummaryDashboardSubscriptionVariables>{ pubId : "90" }
            
            ,result: ( {data,context,errors} ) => { //  is a hook called when a result is received
            let anotherWrongInstance = this // <<--- this instance variable will be wrong ( dont't have the mounted page components ) 
            .... 

-------------- HERE the variable Instance is instance of Vue object ( not containing the data object of the vue-page
------- also the this is WRONG,

correct

get apollo () {

      let instance = this as unknown as StatsDashboardPage
      return   { // this is called before local context being setup ( properties not available )

        $subscribe : {
           
          simplesub1 () {
        let instance2 =  this as unknown as StatsDashboardPage
        return <VueApolloSubscriptionOptions<StatsDashboardPage, TrafficSummaryDashboardSubscription>>{ 
            query : trafficSummaryDashboard
            ,variables: <GQLtypes.TrafficSummaryDashboardSubscriptionVariables>{ pubId : "90" }
            ,result: ( {data,context,errors} ) => { //  is a hook called when a result is received
            
            let correctPageInstance = this // <<--- this now is OK!!
            .... 

-------------- HERE the variable Instance is instance of Vue object ( not containing the data object of the vue-page
-------------- HERE the variable Instance2 is instance of VueComponent  object with everything as expected
------- also the this is CORRECT,

the documented usage is this ( in javascript, but the typescript translation is more like the wrong-first example I've showed than the second-correct one .. ) :

// Apollo-specific options
apollo: {
  // Subscriptions
  $subscribe: {
    // When a tag is added
    tags: {
      query: gql`subscription tags($type: String!) {
        tagAdded(type: $type) {
          id
          label
          type
        }
      }`,
      // Reactive variables
      variables () {
        return {
          type: this.type,
        }
      },
      // Result hook
      result (data) {
        // Let's update the local data
        this.tags.push(data.tagAdded)
      },
      // Skip the subscription
      skip () {
        return this.skipSubscription
      }
    },
  },
},

I've spent 3 days around this issue I hope to save someone's time with that bug report, and I hope someone have the time to update the documentation accordingly :)

thank you!
Francesco

p.s.
note that I've not tested the javascript behaviour if it's correct or not, I've only tested that in typescript..

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions