ember-apollo-client icon indicating copy to clipboard operation
ember-apollo-client copied to clipboard

Suggested Use For WatchQuery on Data-Loading Components

Open topbloc-beiswenger opened this issue 6 years ago • 3 comments

I was unable to find anything in the docs, tutorials, or example projects about how to exactly use watch queries in data-loading components. From the docs, I know that I can use the ComponentQueryManager which will track active watch queries and unsubscribe when the component is destroyed. I also know that watchQuery will return an Ember.Object and can be used in computed properties. What I don't know is how an actual implementation looks. Based on the above information, I would assume that the following works but it does not.

import Component from '@ember/component'
import { computed } from '@ember/object'
import { inject as service } from '@ember/service'
import { ComponentQueryManager } from 'ember-apollo-client'
import query from 'tbui/gql/queries/pets'

export default class SideBar extends Component.extend(ComponentQueryManager) {

  async didInsertElement() {
    let variables = { ownerId: '1' }
    let result = await this.apollo.watchQuery(
      {
        query,
        variables,
      },
      'pets'
    )
    this.set('activeQuery', result)
  }

  @computed('activeQuery')
  get numberOfPets() {
    console.log('query updated')
    return this.activeQuery ? this.activeQuery.length : null
  }
}

The computed property never gets updated even though it is utilized in the template.

topbloc-beiswenger avatar Jul 10 '19 22:07 topbloc-beiswenger

Also I have verified that the cache is changing for the query and the computed property is not changing.

topbloc-beiswenger avatar Jul 10 '19 22:07 topbloc-beiswenger

@topbloc-beiswenger This is a good question. I actually don't know the best way to do this at the moment. I have achieved this in the past using ember-concurrency.

Below is an example of that.

export default class NoteListcomponent extends Component.extend({
  fetch: task(function*() {
    try {
      return yield this.apollo.watchQuery({
        query: MY_QUERY,
      });
    } catch(e) {
      console.log(e)
    }
  })
}) {
  @service
  public apollo;

  @computed('fetch.last'))
  get notes() {
    if (this.fetch.last.value) {
      return this.fetch.last.value.notes
    }
    return [];
  }
}``

Hopefully, this gives you some light.

I will keep this issue open so we can work on documenting this.

josemarluedke avatar Jul 31 '19 22:07 josemarluedke

@josemarluedke Thanks for the response. After doing some digging through other repos that use this library, I stumbled upon ember-caluma which uses similar patterns with ember-concurrency. Still not convinced that this is the best way to do this. It would be really nice nice if we could somehow use an observable in a computed property.

topbloc-beiswenger avatar Aug 01 '19 21:08 topbloc-beiswenger