ag-grid: Vue3 Cell Renderer Setup() method not running

I’m submitting a … (check one with “x”)

[] bug report => see 'Providing a Reproducible Scenario'
[] feature request => do not use Github for feature requests, see 'Customers of ag-Grid'
[x] support request => see 'Requesting Community Support'

I am using Vue 3 and trying to use a cell renderer for an Edit button within an Actions Column. But it seems asif the Setup method is not working when it is being included via the Cell renderer. However, if I include the Component straight into the page it works fine.

This is the error I am getting

Uncaught TypeError: Cannot read property 'apply' of undefined
    at Object.onClick._cache.<computed>._cache.<computed> (actionsColumn.vue?df29:4)
    at callWithErrorHandling (runtime-core.esm-bundler.js?5c40:154)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?5c40:163)
    at HTMLButtonElement.invoker (runtime-dom.esm-bundler.js?830f:292)

This is the Component that is being used

<template>
  <button
    class="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded"
    v-on:click="onEditClick"
  >
    Edit
  </button>
</template>

<script>
  import { computed, defineComponent, ref } from "vue";
  import { mapGetters, useStore } from "vuex";

  export default defineComponent({
    name: "actionsColumn",
    setup() {
      // Setting Up Store
      const store = useStore();

      // Getting SiteData and Route
      const siteData = computed(() => store.getters.siteData);

      // Route and Section
      const route = computed(() => store.getters.getCurrentRoute);
      const section = ref(
        siteData.value.sections[route.value ? route.value : "Home"]
      );

      const onEditClick = () => {
        console.log("Edit");
      };

      onEditClick();
      console.log("editbutton");

      return {
        onEditClick,
      };
    },
  });
</script>

This is the Column Def for that column

{
        headerName: "Actions",
        field: `${section.value.tableName}_id`,
        cellRendererFramework: "actionsColumn",
      }

It is displaying the button in the Grid correctly, it just throws the error when you click the button. The console.log (“editbutton”) inside the setup method also is not being run.

Any help would be greatly apreciated

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 7
  • Comments: 35 (11 by maintainers)

Most upvoted comments

You can use the composition api in cell renderers, but it is janky. The only thing I’ve found that works is using getCurrentInstance(). The larger issue though is there is no example / or possible way that I have found to use application components / dependencies(vue router, router-link, vuex, other globally registered component, etc) inside of an ag grid cell renderer component. I.E. I would much prefer to use the router-link component in the example below instead of creating an anchor tag.

<template>
  <a v-if="url" :href="url" class="grid-link">{{linkText}}</a>
  <span v-else>{{linkText}}</span>
</template>

<script lang="ts">
import {
  computed,
  defineComponent, getCurrentInstance
} from 'vue';
// Ag grid cell renderer support for Vue 3 still isn't quite right.
// Globally registered components also do not work
// params is added to the Component instance (getCurrentInstance) data and is where the cell values are stored.
// params.key is where 'cellRendererParams' defined in a column's columnDef reside
// params.data contains the values for all columns/fields on this cell's row.
export default defineComponent({
  name: 'LinkCell',
  setup() {
    const instance = getCurrentInstance();

    function getParts(): Record<'params'|'data', any> {
      const { params } = instance?.data as Record<'params', any>;
      const { data } = params;
      return { params, data };
    }

    return {
      linkText: computed(() => {
        const { params, data } = getParts();
        const prop: string = params.labelProp;
        const failSafe: string = params.linkLabel ? params.linkLabel : 'View';
        return data[prop] || failSafe;
      }),
      url: computed(() => {
        const { params, data } = getParts();
        const prop: string = params.urlProp;
        return data[prop] ? `#/${data[prop]}` : null;
      })
    };
  }
});
</script>

A note for everyone here - there were a few issues around the first version of our vue 3 offering. This issue along with others should be fixed with 26.0.0, currently scheduled for the end of next week

Hmmm, globally registered components still cannot be used in cell renderers v26.0.0. This doesn’t appear to be fixed.

This PR seems like they attempted to resolve the issue: https://github.com/ag-grid/ag-grid/pull/4601

But it was closed.

I should also note that all examples will (alongside JS, react, angular and vue 2) have a vue 3 version. There is also a vue 3 specific getting started guide (again, to be released next week)

It’s a bug and need to be fixed. Change the render component into Vue3 composite style, you will see an error.

Hmmm, globally registered components still cannot be used in cell renderers v26.0.0. This doesn’t appear to be fixed.

This PR seems like they attempted to resolve the issue: #4601

But it was closed.

@seanlandsman: Just to clarify, since this is the main GitHub issue that comes up when searching for the above limitation: this is still the case, right?

That is, currently there is no way to call e.g. Vue’s inject() or vue-i18n’s useI18n() in the setup() function of a custom cell renderer, correct?

The documentation seems to suggest this here.

thanks for helping verify this @hloehrmann - I’ll be issuing a proper patch release either tomorrow or early next week

You can use the composition api in cell renderers, but it is janky. The only thing I’ve found that works is using getCurrentInstance(). The larger issue though is there is no example / or possible way that I have found to use application components / dependencies(vue router, router-link, vuex, other globally registered component, etc) inside of an ag grid cell renderer component. I.E. I would much prefer to use the router-link component in the example below instead of creating an anchor tag.

Note from my side: you need to call getCurrentInstance in the onBeforeMount lifecycle hook, otherwise the params are not available. It also helps to type the params as ICellRendererParams.

setup() {
    const someValue = ref('');

    onBeforeMount(() => {
      const instance = getCurrentInstance()?.data as Record<
        'params',
        ICellRendererParams
      >;

      const params = instance.params;
      someValue.value = params.value;
    });

    return {
      someValue
    };
  },