Ensure props are properly sanitized in Vue 3 before utilizing them

How can I efficiently clean up props in Vue 3 before using them?

I am faced with the challenge of handling props that can be either objects or stringified JSON versions of those objects. Currently, the application I'm working on tackles this issue by modifying the props in the created method.

However, this approach is not ideal as it triggers warnings from my linter. Since I cannot control the components using my component beforehand, I cannot fix this in the parent before my component is utilized.

After exploring the possibility of utilizing a default option with a method to handle rawData, I attempted the following:

defineProps({ 
  data: {
    type: [Object, String],
    default: ((rawData) => {
      if(typeof rawData === 'string') {
        return JSON.parse(rawData);
      }
      return rawData;
    }
  }
});

Unfortunately, this did not produce the desired outcome. It appears that the default value is only applied when no data is provided, which is expected behavior. Is there a way to achieve this transformation every time, even when data is supplied?

As an alternative solution, I could store the props in refs and then modify them accordingly. However, since I do not require the values to be reactive, this might seem excessive.

Answer №1

If you're looking to convert JSON props, you can utilize the function below:

import { computed, toRefs, Ref } from 'vue'

export function transformJsonProps<T extends object>(props: T): { [K in keyof T]: Exclude<T[K], string> } {
  const refs = toRefs(props);
  return Object.fromEntries(
    Object.entries<Ref>(refs)
      .map(([k, r]) => [k, computed(() => typeof r.value === 'string' ? JSON.parse(r.value) : r.value)])
  ) as any
}
const props = defineProps(...)
const updatedProps = transformJsonProps(props) // processed strings are now parsed

// transformJsonProps.js
import { computed, toRefs } from 'vue';
export function transformJsonProps(props) {
    const refs = toRefs(props);
    return Object.fromEntries(Object.entries(refs)
        .map(([k, r]) => [k, computed(() => typeof r.value === 'string' ? JSON.parse(r.value) : r.value)]));
}
// transformJsonProps.d.ts
export declare function transformJsonProps<T extends object>(props: T): {
    [K in keyof T]: Exclude<T[K], string>;
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the process of manually loading webpack async chunks in the event that a dynamic import fails to load the file?

Async chunks in webpack can be created by using Dynamic Imports (for example: import('./ModuleA.js');). If the dynamic chunks fail to load, I want to retry loading them from another location. After grappling with the issue and delving into babel ...

I noticed that my API call is being executed twice within the router function

In my NextJs project, I am utilizing Express for routing. I have implemented a router with a dynamic :id parameter which triggers an axios call to check the ID in the database. However, I am facing an issue where the API is being called twice when the :id ...

Struggling to implement touch event functionality for CSS3 spotlight effect

I'm experimenting with implementing touch events on an iPad to achieve a certain effect. Currently, I have it working smoothly with mouse events on JSFiddle at this link: http://jsfiddle.net/FwsV4/1/ However, my attempts to replicate the same effect ...

Select Menu (Code Languages:CSS, JS, HTML, BBCode)

I'm currently in the process of setting up a BB code for a forum I moderate. Here's the code snippet I'm using to generate a dropdown box that users can add to the signature field of their profiles: <!DOCTYPE html> <html> <d ...

Is it possible to create a basic calculator with Vue.js by incorporating v-model and possibly v-if?

I am looking to create a Vue.Js component that includes an input field displaying the potential hours saved by a user switching to our software. How can I implement the v-if directive in this scenario? For users spending 20 - 30 hours, they would save 10 ...

Updating the table row by extracting data and populating it into a form

As part of my project, I am implementing a feature where I can input 'Actors' into a table using a Form. This functionality allows me to select a row in the table and retrieve the data of the chosen Actor back into the form for updating or deleti ...

Improving React efficiency: What techniques can be used to prevent the entire component from re-rendering every time a prop changes?

Issue at Hand I created a custom component named PageLayoutSideBar.tsx that accepts two props: sideBar and content. This component is designed to make it easy to display the sideBar and page content with the appropriate styling and sidebar width. My conce ...

Breaking down an array into groups - where did I go wrong in my code?

Check out the following code : function splitArrayIntoGroups(arr, size) { // Splitting the array into groups. var newArray = []; for(var i = 0; i < arr.length; i++){ for(var j = 0; j < size; j++){ newArray.push(arr.splice(0, size)); ...

Error occurs when JSON.parse is used

<!DOCTYPE html> <html> <head> <title></title> </head> <body> <script> var data = "{ 'name': 'John' }"; var result = JSON.parse(data); </script> ...

Need help with TypeScript syntax for concatenating strings?

Can you explain the functionality of this TypeScript syntax? export interface Config { readonly name: string readonly buildPath: (data?: Data) => string readonly group: string } export interface Data { id: number account: string group: 'a&a ...

Increase the time of a Date by 10 seconds

Is there a way to increase the time of a JavaScript date object by 10 seconds? For example: var currentTime = new Date(); var currentSeconds = currentTime.getSeconds() + 10; currentTime.setSeconds(currentTime.getSeconds() + currentSeconds); ...

Steps to activate an event when Windows is loaded

Every time windows load, I want to run $('select[name="order_id"]').change(), but it's not working as expected. After debugging in the browser console, I can see that the script $('select[name="order_id"]').cha ...

Tips for safeguarding your passwords across diverse authentication methods

Exploring a new project idea, I am interested in supporting the SASL Mechanisms for authentication, particularly PLAIN and DIGEST-MD5. I am curious about how to securely store users' passwords when implementing these two authentication methods. When ...

How can Vue be utilized to display static data in a modal window?

I have a pair of 'cards' containing the following content: <div class='card'> <span>title one </span> <button @click='open = !open'>show</button> </div> <div class=& ...

Determine the output based on the data received from the ajax post request

I am seeking a way to validate my form based on the data returned. Currently, the validation only returns false if the entire post function is false. Is there a solution to differentiate how it is returned depending on which condition is met? This is my ...

The Laravel Mix Hot Module Replacement (HMR) server fails to start up

Laravel Mix Version: 6.0.43 Node Version (node -v): 16.13.1 NPM Version (npm -v): 8.1.2 OS: Windows 10 21h2 Description: Encountering an issue on a fresh installation of Laravel and other existing projects. When running npm run hot, the script tag sourc ...

I am facing an issue with incorporating dynamic imports in the configuration of my Vue router

Currently working on a Vue.js web page using webpack 4 and babel 6 for asset compilation. Encountering an issue when trying to use route('home', '/', () => import('../pages/home.vue')), as the compiler is throwing an error ...

The Challenge of Azure App Service Connection Timeouts

We are currently facing an issue with our Azure App Service, which is built in C# .NET 4.7. The application works perfectly fine when running locally, but encounters an error upon publishing to Azure. The error message returned to the client (web UI develo ...

JavaScript embedded in an HTML document, which in turn is embedded within JavaScript

Is it possible to nest tags within other tags to control the functionality of a download button in a chat bot? Unfortunately, nesting tags is not allowed, so I'm looking for an alternative solution. Below is the complete HTML file I'm working wit ...

What is the best way to retrieve Firebase data and assign it to a variable in React after using setState

Working with react and firebase real-time database for the first time has been quite challenging. I'm struggling to extract the data and insert it into a constant called items. It seems like the firebase code is asynchronous, which means it executes a ...