Automatically generate nested object properties in VueJS for streamlining code structure

Understanding the Issue

I have created a custom system to monitor specific "store" properties from a JSON in a NoSQL database. The structure is fairly straightforward, with nested objects that are necessary for various reasons.

The data format resembles this:

{
    store: {
        objA: {
            objB: {
                prop1: 'some value'
            }
        }
    }
}

However, when fetching the data from the NoSQL database, objB may not always be present.

Example of Template Usage

I am using custom components that rely on these data store properties:

<my-selector :value.sync="store.objA.objB.prop1">
</my-selector>

If "objB" is missing, it results in a crash with the typical JavaScript error indicating that it cannot retrieve "objB" from undefined, which is expected.

I am seeking a VueJS solution to handle this scenario.

Possible Solutions

To prevent this crash:

  • Avoiding the use of v-if to hide the selector when "objB" is absent, as the selector should still be accessible even without all data being set (e.g., optional data).
  • Adjusting the "load" function responsible for fetching data from the database to initialize the required properties (like objB) before assigning data to the data store. However, this approach would involve pre-defining these properties within the initial VueJS data object, a workaround I may resort to if no other feasible options emerge.
  • A preferable choice involves creating a directive or another template-based solution to automatically add missing properties.

VueJS Binding Evaluation

One potential solution includes:

<my-selector v-autocreate="'store.objA.objB.prop1'" :value.sync="store.objA.objB.prop1">
</my-selector>

However, the "v-autocreate" directive binding does not take precedence initially, according to my debugging attempts. Documentation regarding the loading order of directives and attributes seems scarce.

My aim was to access all bindings of a node using the "bind" directive in order to avoid repetitive strings, similar to how we can do so in knockoutjs. Unfortunately, this functionality appears unavailable in VueJS.

While I aspire to achieve this goal, its feasibility remains uncertain. A hypothetical event like a pre-bind or beforeBind event on a directive could potentially help:

<my-selector v-autocreate :value.sync="store.objA.objB.prop1">
</my-selector>

In this case, v-autocreate would ensure the vm.$set of any missing properties.

Answer №1

One way to handle object paths is by creating a method that iterates through each property, creates it if necessary, and finally returns the value of the last property.

Here's an example (not tested):

function getObjectProperty(object, path) {
    path = path.split('.')

    let index = 0
    const length = path.length
    let val
    while (object != null && index < length) {
        let key = path[index++]
        if(object[key] == null) {
            object[key] = {}
        }
        object = object[key]
    }
    return val
}

To use this method:

<my-element :value="getObjectProperty(obj,'prop1')">
</my-element>

If you're looking for a more robust solution, check out lodash's get function which inspired this code snippet.

https://github.com/lodash/lodash/blob/master/get.js

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

Encountering memory leaks and displaying repetitive data due to having two distinct observables connected to the same Firestore

I am currently utilizing @angular/fire to retrieve data from firestore. I have two components - one serving as the parent and the other as the child. Both of these components are subscribing to different observables using async pipes, although they are bas ...

Looking for guidance on building a real-time React application with automatic data fetching linked to a nodejs backend

I have a simple question, I have developed an app that retrieves data from a backend server, Now, the app needs to be accessed and edited by multiple users simultaneously while ensuring that all changes made to the list are reflected in real-time for ever ...

I am struggling to extract data from the spawned Node.js child process. What am I overlooking?

Trying to utilize a spawned command-line process for lzip in order to expand an lzipped data stream due to the lack of suitable native JavaScript tools. Succeeded in achieving this by working with files and file descriptors, although cumbersome to handle ...

ngClass binding fails to update when using directives to communicate

I am looking to combine two directives in a nested structure. The 'inner directive' includes an ng-class attribute that is bound to a function taking parameters from both inner and outer scopes, and returning a Boolean value. This is the HTML co ...

"Exploring the possibilities of customizing Material UI tabs and implementing a tabs scroller

I'm currently trying to customize the appearance of these MUI tabs, specifically the tab color and bottom border color. Despite my attempts using makeStyles and other methods, I haven't been able to achieve the desired result. Here is an example ...

Struggling to configure webpack with Babel for client-side development

Find the complete code here I am currently attempting to integrate Vue Single File Components using express/handlebars. Following the guidelines on this Vue page, I proceeded to install Webpack (and then Babel). At first glance, it seems that Webpack is ...

Unit testing controllers in AngularJS with Karma often involves setting up mock services to simulate dependencies

Currently, I am immersed in the development of a Single Page Application using AngularJS as part of my Treehouse Full Stack JavaScript TechDegree. My main focus right now is on conducting unit tests for the controllers. The challenge lies in testing contro ...

Creating a JSON File with an Illustrator Script

Currently, I've been working diligently on developing a system that allows me to export my swatches from Illustrator as a JSON object. This will greatly simplify the process of updating my App. By utilizing the illustrator scripting API, I've suc ...

A Complication Arises with Browser Functionality When Embedding an Iframe within

I am experiencing a peculiar problem while embedding an iframe with a specific src inside an absolutely positioned div. Here's the basic structure of the webpage: .container { position: relative; overflow: hidden; width: 100%; heigh ...

Is it possible to modify the inactive color of just one radio button in Framework7?

Is there a way to change the inactive color of only one radio button in Framework7? I am aware that using the CSS variable --f7-radio-inactive-color allows me to set the inactive color for all radio buttons. However, I specifically want to modify the inac ...

Ways to share data between components in Vue.js

Currently, I am looking to search for products and my data is organized within the categories container. The project's structure has been attached here. I am wondering how exactly the searchItem function retrieves the necessary information from the ca ...

JavaScript - Issue encountered while reaching the bottom of the webpage

While conducting tests using Firebug/Firefox, I am trying to execute a simple command that will scroll the page to the bottom. Here is the command: window.scrollBy(0,3000); Seems straightforward, right? When testing on certain websites like Yahoo.com ...

What is the relationship between three.js transforms and CSS3 3D-transforms?

I am developing a unique open-source tool for exploring and visualizing the complexities of human anatomy. At the center of this tool is a dynamic 'chessboard' that occupies the majority of the screen. As you drag the board, various CSS3 3D-tran ...

Typescript gives you the ability to create a versatile writing interface that includes all

Think about this: interface Options { length?: number, width?: number } interface Action { performAction ({length, width}: Options): void } const myObject: Action = { performAction ({length, width}) { // do something without returning ...

AngularJS and ExpressJS clash in routing (Oops, Crash!)

When setting up routing in angularjs and expressjs, I have created app.all('/*'...) to enable rendering index.html. However, whenever I use /*, the page crashes with an "Aw, Snap!" message. angularjs home.config(function($routeProvider,$locatio ...

Implementing a dynamic like functionality using Ajax in Django

I've created a new structure for the like button, but it's not functioning correctly. Here are the files I'm working with: models.py class Comment(models.Model): title = models.CharField(max_length=50) author = models.ForeignKey(Pr ...

Why does my ForEach function in ReactJs automatically execute without being called?

I am creating a function with a ForEach loop that automatically executes and renders the screen without being called. My goal is to have the startGame function update the element at position [1] of the array to be 5 when I click on it. However, as soon as ...

Enrollment in the course is conditional on two words being a perfect match

I have a concept in mind, but I'm struggling to piece it together. I have bits of different methods that just don't seem to align. That's why I'm reaching out for your expertise. Let's say I have 3 content containers with the clas ...

Creating a dynamic JSON array with a single key as an array

After converting data from an excel sheet into a json array, here is the structure: [{ 'booktitle': 'Leading', 'bookid': '56353', 'bookauthor': 'Sir Alex Ferguson' }, { 'booktitle&ap ...

Employing a content delivery network library within a Vue component

Seeking assistance with incorporating scrollreveal into my Vue components. I have added the following script tag: <script src="https://unpkg.com/scrollreveal"></script> close to the closing body tag in my public/index.html My expec ...