1

I have component MyComponent.vue where I have data value that constantly changes. I want to pass this value to javascript file(js file should know about changes of value everytime)

Why do I do that? Because my regular js file is a service layer for axios methods. I can import this file in many other components. The file contains axios methods and urls are dynamic. I want those urls depend on data variable. This data variable comes from MyComponent.js

So the main goal is to make dynamic urls of axios that depend on data variable

I tried some code but it doesn't work, because js file(CategoryService.js) know nothing about this.categoryNumber.

MyComponent.vue:

<script>
export default {
data() {
return {
categoryNumber: 1
   }
  }
}
</script>

CategoryService.js

import http from "../../../http-common";

let category = "category1";

if (this.categoryNumber === 1) {
    category = "category1";
} if (this.categoryNumber === 2) {
    category = "category2";
}

class CategoryService {
    get(id) {
        return http.get(`/${category}/${id}`);
    }

    update(id, data) {
        return http.put(`/${category}/${id}`, data);
    }

    create(data) {
        return http.post(`/${category}`, data);
    }

    delete(id) {
        return http.delete(`/${category}/${id}`);
    }

    getAll() {
        return http.get(`/${category}/all`);
    }
}

export default new CategoryService();
1
  • Why not add one more argument to each method. e.g. create(category_number, data) {} so the methods expect two arguments Commented Jul 14, 2020 at 13:32

2 Answers 2

1

So with a bit of refactoring, you could easily get this working.

First of all, I would put the if/else logic of your class into it.

For convenience and scalability, I would use a Vuex store that will keep track of your categoryNumber and share it accross all your components.

Then I would bind my service to my Vue instance so I can easily access it in all my components as well as the store and I would pass the latter to my class as a parameter.

For the last part, I don't know the logic in the http-common file so the code I will show you is a bit nasty. But depending on wether or not you bound 'http' to axios, you could make use of axios interceptors to call the getCategoryNumber() method in every request.

Here's an idea of the implementation I would go for:

const CategoryService = class CategoryService {

  constructor(store) {
    this._store = store;
    this.category = "category1";
  }

  getCategoryNumber() {
    if (this._store.state.categoryNumber === 1) {
      this.category = "category1";
    }
    if (this._store.state.categoryNumber === 2) {
      this.category = "category2";
    }
    console.log(this.category); // for demo puprose
  }

  get(id) {
    this.getCategoryNumber(); // We could use axios request interceptor instead of calling that in every route, but that works !
    return http.get(`/${this.category}/${id}`);
  }

  update(id, data) {
    this.getCategoryNumber();
    return http.put(`/${this.category}/${id}`, data);
  }

  create(data) {
    this.getCategoryNumber();
    return http.post(`/${this.category}`, data);
  }

  delete(id) {
    this.getCategoryNumber();
    return http.delete(`/${this.category}/${id}`);
  }

  getAll() {
    this.getCategoryNumber();
    return http.get(`/${this.category}/all`);
  }
}

const store = new Vuex.Store({
  state: {
    categoryNumber: 1
  },
  mutations: {
    setCategoryNumber(state, payload) {
      state.categoryNumber = payload;
    }
  }
});

// Bind your service to the Vue prototype so you can easily use it in any component with 'this.$service'
// pass it the store instance as parameter
Vue.prototype.$service = new CategoryService(store);

new Vue({
  el: "#app",
  store, // dont forget to bind your store to your Vue instance
  methods: {
    updateCategoryNumber() {
      // Put here any logic to update the number
      this.categoryNumber = this.categoryNumber === 1 ? 2 : 1;
      this.checkServiceCategoryValue();
    },
    checkServiceCategoryValue() {
      // for demonstration purpose
      this.$service.getCategoryNumber();
    }
  },
  computed: {
    // Look for the store value and update it 
    categoryNumber: {
      get() {
        return this.$store.state.categoryNumber;
      },
      set(value) {
        this.$store.commit("setCategoryNumber", value);
      }
    }
  }
});
<div id="app">
  <h2>number: {{ categoryNumber }}</h2>
  <button type="button" @click="updateCategoryNumber()">
    updateCategoryNumber
  </button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/[email protected]"></script>

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

Comments

0

Thanks to @Solar I just added one more parameter for all urls and put the number of category to it

CategoryService.js:

class CategoryOneService {
    get(id, category) {
        return http.get(`/${category}/${id}`);
      }

      getAll(category) {
        return http.get(`/${category}/all`);
      }

    }

functions.js:

let catNum = "";

function getQuestion() {

    if (this.categoryNumber === 1) {
        catNum = "category1";
    }

    if (this.categoryNumber === 2) {
        catNum = "category2";
    }
    let questionId = this.questionNumber;
    CategoryOneService.get(questionId, catNum)
        .then(response => {
            this.question = response.data.question;
            this.answer = response.data.answer;

        })
        .catch(error => {
            console.log(error);
        });
}

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.