Alpine: [Question] - What is the best way to access x-data data from js

Created on 27 Feb 2020  路  10Comments  路  Source: alpinejs/alpine

I have a dropdown that I would like to serialize and include in an ajax request, but I'm having a hard time getting the selected states of the dropdown. Is there a way to access the contents of x-data from outside the scope of the component?

For example, with vue I can access it using properties on the vue app object:

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})

console.log(app.message) // reads 'Hello Vue!'

Most helpful comment

Thanks so my for your help @HugoDF. Solves my problem perfectly. It also works to change the values of data via JS and have the component react to changes.

@calebporzio is this an internal API that shouldn't be relied on? Or is that relatively stable?

All 10 comments

You should be able to use this.yourPropertyName.

For example:

<div x-data="page()">
  <button @click="fetchData()">Fetch</button>
</div>  
<script>
  function page() {
    return {
      message: 'Hello world',
      fetchData() {
        console.log(this.message);
      } 
    }
  }
</script>

In order to do what you describe, you might need to build it as follows:

<div x-data="page()">
  <select x-model="selectedOption">
    <option value="">Select an option</option>
    <template x-for="option in options">
      <option
        :key="option.value"
        :value="option.value"
        x-text="option.text">
      </option>
    </template>
  </select>
  <button @click="fetchData()">Fetch</button>
</div>  
<script>
  function page() {
    return {
      message: 'Hello world',
      selectedOption: '',
      options: [
        {
          value: 'bacon',
          text: 'Bacon'
        },
        {
          value: 'ham',
          text: 'Ham'
        }
      ],
      fetchData() {
        console.log(this.selectedOption);
      } 
    }
  }
</script>

Thanks @HugoDF!

@calebporzio how would you feel if I contributed a "cookbook" to this repo? Documenting common questions like this one

Sorry - I may not have made my question clear. I know how to access the data from in-scope in the JS object (and your example does a good job showing that). I was curious how to access it from out of the scope of the x-data object?

@hamrickdavid I think you can access the relevant Alpine.js component instance using element.__x, Alpine.js components have a $data property see https://github.com/alpinejs/alpine/tree/master/src/component.js

So element.__x.$data should work off the top of my head/reading the code will get back to you with an example later if this doesn't work.

Thanks so my for your help @HugoDF. Solves my problem perfectly. It also works to change the values of data via JS and have the component react to changes.

@calebporzio is this an internal API that shouldn't be relied on? Or is that relatively stable?

@hamrickdavid I think it falls under "stable but use at your own risk" ie. It's not a documented feature, but I don't think it's likely to change

You could hoist a reference of your object into the global scope before passing it to Alpine

<div x-data="create_model()">...</div>

<script>
  function create_model() {
    window.model = {
      'username': 'some_data'
    }
   return model
  }
</script>

which you can access in the console at window.model or just model

@jastrauss I'm not sure that'll reference the value in Alpine state (which takes the initial state and wraps it in a Proxy in order to implement reactivity)

It works in version 2.4! You can read the data but not write to it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

imliam picture imliam  路  5Comments

maxsite picture maxsite  路  4Comments

dstpierre picture dstpierre  路  4Comments

ryangjchandler picture ryangjchandler  路  3Comments

haipham picture haipham  路  4Comments