javascriptrecursionvuejs2vue-filter

How to make Vue Filter recursive?


I had a function that i needed to use in different components so I decided to make a vue Filter. The problem is that the function is recursive, it's call itself, but I don't know how to do in a Vue Filter.

In fact, I solved the issue, but I am not really satisfied with my solution, in the parameters of the filter I give the instance of vue and then call one more time the filter from the given instance...

-- component.vue
if (this.$options.filters.arraysAreEquals(array1, array2, this)) {
    console.log("Arrays are equals")
}


-- main.js
Vue.filter('arraysAreEquals', (x, y, self) => {
    if(x.length != y.length){
        return false;
    }
    if(x instanceof Array) {
        if(!(y instanceof Array)){
            return false;
        }
        for(let i = 0; i < x.length; i++) {
            if(!self.$options.filters.arraysAreEquals(x[i], y[i], self)){
                return false;
            }
        }
    } else {
        return x == y;
    }
});

So my question is how can I should do the recursion without giving the vue instance (self in my case)? Thanks you.


Solution

  • First of all I'm not a Vue.js user, but doing recursion is quite simple. The problem you're facing is due to the fact that the function is anonymous. These can by definition not be recursive (when not assigned to a handle like a variable or a name), because they have no handle to call themself. To solve this issue simply store the function in a variable first (or create a named function).

    let filter = (x, y) => {
        if (x.length != y.length) return false;
        if (!(x instanceof Array)) return x == y;
        if (!(y instanceof Array)) return false;
    
        for (let i = 0; i < x.length; i++) {
            if (!filter(x[i], y[i])) return false;
        }
    };
    
    Vue.filter('arraysAreEquals', filter);
    

    By assigning the anonymous function to a variable, we've created a simple handle for us to call inside the function.

    While using this approach keep in mind that you shouldn't reassign the filter variable, since that would effect the recursive call.

    let kaas, other;
    
    kaas = (baas = false) => baas ? 'baas' : kaas(true);
    console.log('kaas() //=>', kaas());
    
    other = kaas;
    console.log('other() //=>', other());
    
    kaas = true;
    try {
      console.log('other() //=>', other());
    } catch (error) {
      console.error(error.message);
    }