Search code examples
javascriptvue.jsvuejs2apollovue-apollo

VueJS components prop execution order


I'm using vuejs and vue-apollo in my project.

I have to components : GroupList and GroupForm

The thing is that I first arrive on the list, and then when I click on one of the groups, I arrive in the form view of that group. To do that, I have a button that opens the form view by giving the id of that group :

openGroupFormView (group, index) {
  this.$router.push({ name: 'GroupFormView', params: { groupId: group.id } })
}

In the past, I used to pass the group object as paramater and it worked but I changed my mind and now I want to pass the id so that when the component GroupForm is opened, the graphql query to retrieve this group based on the id is executed. I want to do that in order to avoid apollo-cache inconsistencies in case where someone edited the same group in the meantime.

So in my GroupForm component I have :

My prop :

props: {
  groupId: Number
}

My component query :

apollo: {
  group: {
    query: GROUP_QUERY,
    variables () {
      return {
        id: this.groupId
      }
    },
    ..
}

The associated query beneath that :

const GROUP_QUERY = gql`
  query ($id: ID) {
    group (id: $id) {
      id
      name
      usersCount
      userIds {
        id
        username
      }
    }
  }
`

My problem is that in data () of my component, I used to use the group that I passed through the props as an object. Now, I still want to do things on the group but the apollo part is executed after the data () part so I have an undefined problem. How could I ensure that this problem doesn't occur ? I mean that apollo query is run first.

My data() block :

data () {
  return {
    form: {
      name: this.group === undefined ? '' : this.group.name
    }
  }
},

Thanks in advance for your help !

EDIT : A part of my template

  <b-form>
    <b-form-group label="Name">
      <b-form-input
        type="text"
        v-model="form.name"
        required
        :disabled="!editing"/>
    </b-form-group>
    <div v-if="editing" class="mb-3">
      <b-button @click="cancelEdit()">Cancel</b-button>
      <b-button @click="group === undefined ? createGroup() : updateGroup(group)" variant="success">Save</b-button>
    </div>
  </b-form>

Solution

  • I don't use Apollo but it looks like you should be able to initialize name to an empty string and then use the result hook to set it when the query completes.

    Untested:

    apollo: {
      group: {
        ...
        result({ data, loading, networkStatus }) {
          this.form.name = data.name // something like this
        }
      }
    }