-1

Is there a way to enforce the format of data-attributes?

Considering the following situation, the returned value is often a string – not an array. splitting is not always desirable, for instance, if the values contain commata. There is a way (see "day3"), but you usually have a variable to pass and not a literal string.

<script setup>
const as_variable = ["Lunes", "Martes", "Miercoles", "Jueves"];

const test_read_all_da_data = ( ev ) => {
  const el = ev.currentTarget;
  console.log(JSON.parse(el.dataset.days1));
  console.log(JSON.parse(el.dataset.days2));
  console.log(JSON.parse(el.dataset.days3)); // only this one is array of strings, as desired.
  console.log(JSON.parse(el.dataset.days4));
};
</script>

<template>
    <button 
        :data-days1="['Lunes', 'Martes', 'Miercoles', 'Jueves']"
        :data-days2='["Lunes", "Martes", "Miercoles", "Jueves"]'
        data-days3='["Lunes", "Martes", "Miercoles", "Jueves"]'
        :data-days4="as_variable"
        @click="test_read_all_da_data">data-attributes</button>
</template>
4
  • What is the purpose of what you are doing? data-days3 works because it is a valid json string. Commented Apr 10 at 20:47
  • What I want to do is to maintain the type (boolean, number, etc.). Sometimes the type is important. Reading el.dataset.myprop always returns a string. This JSON.parse() approach (which I actually wrap in try … catch and a readDataAttribute() method but I've left out to simplify the question) lets me maintain or restore the type. But arrays have been more tricky. Commented Apr 12 at 7:00
  • May I ask where does the data source come from? does it need to be in the template? From my experience, manipulating the string is always harder and unexpected result can comes up. Better choice could be handle it inside script, button should trigger the event to run some function to get/filter data from a data source (properly an object, maybe typescript also can use there to enforce the type) Commented Apr 14 at 8:19
  • That's what I'm saying. I would have to use the way data-days3 does it, but I'm usually bound to using variables like in data-days4. Commented Apr 14 at 15:04

1 Answer 1

-1

I just realized that this is due to Array's toString method. You can just write a custom one.

<script setup>
Array.prototype.toDataString = function() {
  return `[${this.map((item) => typeof item === 'string' ? `"${item}"` : item)}]`;
};
</script>

<template>
  <button :data-days4="problematic_list.toDataString()" …>success!</button>
</template>

… or an extra method for that purpose

const toDataString = ( list ) => {
  if (!Array.isArray(list)) { return list; }
  return `[${list.map((item) => typeof item === 'string' ? `"${item}"` : item)}]`;
};
Sign up to request clarification or add additional context in comments.

2 Comments

It's a bad practice to modify builtins for local purposes, stackoverflow.com/questions/14034180 . toDataString can be a function with the same level of usefulness
Yes, that's also possible.

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.