0

In my Drupal 7 site's html I have this

<script>$L = $L.wait(function() {
(function($) {
      Drupal.behaviors.related_products = {
        attach: function (context, settings) {
          artiklar = Drupal.settings.related_products.artiklar;
          console.log(artiklar);
        }
      };
    })(jQuery);
});</script>

In the variable artiklar above I have some data that I have passed from the server side using Drupal behaviors. Now, on the client side I need to access the variable artiklar in a Vue component, like so:

Vue.component('artikel-lista', {
    template:`
        <ul>
          <artikel v-for="artikel in artiklar">{{ artikel.title }} Pris: {{artikel.price}} <a :href="artikel.link" class="button tiny" target="_blank">Läs mer</a></artikel>
        </ul>
    `,

    data(){
      return {
        artiklar: "",
      };
    },

    mounted: function(){
      this.artiklar = artiklar // how can I access the variable "artiklar" here
    },

});

The data in the variable consists of an array of items, that I need in my Vue component. But how can I pass the variable from within the script tags to the Vue instance, that lives in a separate file, inserted just before the ending body tag. Anyone?

3
  • its about context/ scope not about files - eventbus can be a keyword Commented Nov 27, 2019 at 15:37
  • Would you be able to assign the artiklar value to the page's hidden input type and access it in vue via: document.getElementById('hiddenFieldId').value? Commented Nov 27, 2019 at 15:45
  • Angelo: I tried your suggestion, and it works fine to assign the value to a hidden input, but then it is impossible to fetch that value with querySelector() or getElementById(), something to do with scope probably as EstraDiaz suggests. Commented Nov 28, 2019 at 10:37

2 Answers 2

1

If you have data in the globally visible Drupal.settings.related_products.artiklar object then you can refer to it practically the same way in Vue.js. or if you must use this function, assign data to global scope window.*.

new Vue({
  template: `<div>{{foo}} / {{bar}}</div>`,
  data() {
    return {
      foo: Drupal.settings.related_products.artiklar,
      bar: window.artiklarData
    };
  }
}).$mount("#app");
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">Vue App</div>

<script>
  // simulate global variable
  var Drupal = {
    settings: {
      related_products: {
        artiklar: ['fus', 'ro', 'dah']
      }
    }
  };
  (function() {
    window.artiklarData = Drupal.settings.related_products.artiklar;
  })();
</script>

If you assign the value to Drupal.settings.related_products.artiklar after creating the Vue object, you can try to use the solutions described in the documentation, e.g.

const vm = new Vue({
  template: `<div>{{foobar}}</div>`,
  data() {
    return {
      foobar: 'Initial value'
    };
  }
}).$mount("#app");

setTimeout(() => {
  // simulate global variable
  var Drupal = {
    settings: {
      related_products: {
        artiklar: 'Changed value'
      }
    }
  };

  (function() {
    vm.foobar = Drupal.settings.related_products.artiklar;
  })();
}, 2000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">Vue App</div>

Maybe you could use RxJS but I don't have enough knowledge to tell if it's true and give an example.

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

1 Comment

Thanks a lot.. I tried with both window.artiklarData and document.artiklarData and I can access it in the console, so it exists, but in my js file where the Vue instance lives, this global is "undefined".... probably something to do with scope?
0

Just in case anyone else is struggling with the same thing, I post this answer to my own question (I accidentally posted the question with the wrong account). In the end it turns out that the answer from Gander was correct and that I could access the variable directly in the Vue component, w/o first stashing it an a global variable. The viewed result was kind of weird though and after some trialling I found out that I had to parse the result with JSON.parse(). This is the working code now:

Vue.component('artikel-lista', {
    template:`
        <ul>
          <artikel v-for="artikel in artiklar">{{ artikel.title }} Pris: {{artikel.price}} <a :href="artikel.link" class="button tiny" target="_blank">Läs mer</a></artikel>
        </ul>
    `,
    data(){
      return{
      artiklar:""
    }
    },
    mounted:function(){
        this.artiklar = JSON.parse(Drupal.settings.related_products.artiklar);
        console.log(this.artiklar);
  }


});

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.