2

I got a class, that was defined in the same Component File, but out of scope for the data, that i am exporting. I'd like to simply call the function, that was defined inside the "export default", but as i am doing, I'm getting the following error, as the map function is not inside the scope:

Test.vue?t=1751457112648:55 Uncaught TypeError: this.map is not a function` -

That is the file i am working with:

<template>
</template>
<script>
class SimpleTest {
  pong() {this.map();}
}
export default {
  name: 'Test',
  data() {
    return {
      init: false,
    }
  },
  methods: {
    map() {return "Simple Return";},
  },
  mounted() {
    let simpleOne = new SimpleTest();
    simpleOne.pong();
  }
}
</script>
3
  • The question lacks stackoverflow.com/help/mcve , SimpleTest isn't used anywhere. It's unclear how the component and SimpleTest are related. But SimpleTest doesn't have map method, this.map() shouldn't be expected to exist. "I'd like to simply call the function" - this could be XY problem, consider explaining in details what you want to achieve instead of focusing on potentially wrong way to do this Commented Jul 2 at 12:55
  • @EstusFlask yea no worries, i got you - but i think in general you get the idea of it - it's not really unclear, is it? And we all know, that "this" is not in the scope, that is why i am asking for an answer, not obvious conversations. Commented Jul 2 at 12:59
  • This depends on what you're trying to achieve in the end. Probably you don't need a class at all. I posted several ways in which this could be handled Commented Jul 2 at 13:25

1 Answer 1

1

Accessing a scope outside a class suggests there's a potential problem with class design. This could be written in several different ways.

This would be a quickfix that doesn't solve the design problem:

simpleOne.pong.call(this);

Generally a class or a method needs to be injected with a function or object. This could be simple but this contradicts the principle of least privilege and gives instance to the whole this instance:

class SimpleTest {
    constructor(instance) {
      this.instance = instance;
    }
    pong() {
      this.instance.map();
    }
}
...
let simpleOne = new SimpleTest(this);
simpleOne.pong();

It's a better design to give it the access to the exact part of the instance it needs. Component methods are bound to the instance and can be passed as callbacks:

class SimpleTest {
    pong(map) {
      map();
    }
}
...
let simpleOne = new SimpleTest();
simpleOne.pong(this.map);

This isn't a good use case for classes because SimpleTest is stateless, and map doesn't make use of component instance. This could be achieved with plain functions:

function map() {...}

function pong() { ping() }

In case map uses component instance and pong needs to be declared outside a component, reusable functionality can be put to a mixin with options API:

let testMixin = {
  methods: {
    pong() {
      this.map();
    }
}
...
mixins: [testMixin],
methods: {
  map() {...},
},

This would be designed differently with composition API through composables.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.