The createElement function in Vue.js does not always return a fully formed component

There is a scenario where I need to create a functional component for a specific purpose. The task at hand involves taking all the children elements and adding some additional props to them, but only to those that are custom components of type ChildComponent. Here is my approach:


MySpecialComponent.vue

    render: function(createElement, context){
        const preparedChildrenLevel1 = context.children.map(child => {
            if(child.componentOptions.tag !== "ChildComponent"){
                return child;
            }

            return createElement(
                ChildComponent,
                {
                    props: {
                        ...child.componentOptions.propsData,
                        level1: "level1"
                    }
                },
                child.componentOptions.children
            )
        });
    },

This method works well. However, when I try to further iterate through the preparedChildrenLevel1 array to add another prop to the children components of type ChildComponent, I encounter an issue where child.componentOptions.tag returns undefined.


MySpecialComponent.vue

    render: function(createElement, context){
        //First level of adding props to children
        const preparedChildrenLevel1 = context.children.map(child => {

            //Here, child.componentOptions.tag is 'ChildComponent'
            if(child.componentOptions.tag !== "ChildComponent"){
                return child;
            }

            return createElement(
                ChildComponent,
                {
                    props: {
                        ...child.componentOptions.propsData,
                        level1: "level1"
                    }
                },
                child.componentOptions.children
            )
        });

        //Second level of adding props to children
        const preparedChildrenLevel2 = preparedChildrenLevel1.map(child => {

            //Here, child.componentOptions.tag is now 'undefined'
            if(child.componentOptions.tag !== "ChildComponent"){
                return child;
            }

            return createElement(
                ChildComponent,
                {
                    props: {
                        ...child.componentOptions.propsData,
                        level2: "level2"
                    }
                },
                child.componentOptions.children
            )
        });
    },

I require this hierarchical access to such specific components across multiple levels.


Note: Below is the complete implementation of the component and how it is utilized.

MySpecialComponent.vue

<script>
export default {
    name: "MySpecialComponent",

    functional: true,

    render: function(createElement, context){
        //First level of adding props to children
        const preparedChildrenLevel1 = context.children.map(child => {

            //In here, child.componentOptions.tag equals 'ChildComponent'
            if(child.componentOptions.tag !== "ChildComponent"){
                return child;
            }

            return createElement(
                ChildComponent,
                {
                    props: {
                        ...child.componentOptions.propsData,
                        level1: "level1"
                    }
                },
                child.componentOptions.children
            )
        });

        //Second level of adding props to children
        const preparedChildrenLevel2 = preparedChildrenLevel1.map(child => {

            //Now, child.componentOptions.tag is 'undefined'
            if(child.componentOptions.tag !== "ChildComponent"){
                return child;
            }

            return createElement(
                ChildComponent,
                {
                    props: {
                        ...child.componentOptions.propsData,
                        level2: "level2"
                    }
                },
                child.componentOptions.children
            )
        });
    },
}

</script>




MainApp.vue

<template>
    <MySpecialComponent>
        <p>child1</p>
        <p>child2</p>
        <ChildComponent :level0="level0">child3</ChildComponent>
        <p>child4</p>
        <ChildComponent :level0="level0">child5</ChildComponent>
        <ChildComponent :level0="level0">child6</ChildComponent>
    </MySpecialComponent>
</template>

Answer №1

When the component is not of type ChildComponent, there won't be any child.components in it, so you need to include an additional condition check:

if(!child.componentOptions || child.componentOptions.tag !== "ChildComponent") {
    return child;
}

This will ensure that only a ChildComponent is passed through the rest of your code.
And by the way, remember that you are not returning anything in the render function of MyHigherOrderComponent.

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

Unique Javascript Library Focused on AJAX

Looking for a specific JavaScript library that focuses solely on AJAX functionality, such as a basic XMLHttp wrapper. ...

Modify and improve promise and promise.all using the async/await feature of ES2017

I have successfully implemented a photo upload handler, but I am now exploring how to integrate async await into my code. Below is the working version of my code using promises: onChangePhotos = (e) => { e.preventDefault() let files = e.target ...

Why does the final value appear when passing an incrementing counter as a prop to multiple React Components created in a loop?

I am currently unraveling the concept of closures in JavaScript. Within this code snippet, I am cycling through the values of the 'items' array using a foreach loop. I have defined a let variable named "count" outside the scope of the loop. Afte ...

What causes Three.js OBJ conversion to render as mesh successfully but log as undefined?

I'm just getting started with Three.js and I'm experimenting a lot. Although I'm new to Javascript as well, the issue I'm facing seems to be more about variable scoping and callback function protocols than it is about Three.js itself... ...

What is the method of aligning content to the left side in a slick slider?

My slider is set up to display three elements, but I'm having trouble aligning one or two elements to the left instead of centering them. jQuery(function () { jQuery('.slider-blog').slick({ arrows: false, dots: true, ...

The issue arises in Selenium IDE when a variable is mistakenly identified as a string instead of a

Hey there, I've encountered an issue while using Selenium IDE. I'm trying to increment a variable by two, but instead of performing numerical addition, it seems to be concatenating strings. <tr> <td>store</td> <td> ...

Steps to implementing a function just before a form is submitted

Imagine a scenario where you have the following HTML form: <form action="myurl.com" method="post" id="myForm"> <input type="number" name="number" class="numberInput"> <input type="number" name="number"> <input type="submit ...

What happens to the parent scope in Javascript when declaring a subclass and why does it get overridden?

I have two classes in JavaScript, with one inheriting from the other. The structure is as follows: var Parent = (function(){ var self; var parent = function(){ self = this; self.type = 'Parent'; }; parent.protot ...

Tips for incorporating inline images with gatsby-image

Seeking Solution In my quest to query and showcase images with a maximum width of 350px, I am hoping to have them displayed inline-block for tablets and larger screens. Ideally, each image would sit next to one another and wrap if they exceed the parent d ...

JavaScript failing to retrieve JSON information from PHP

I seem to be encountering an issue when trying to read JSON data that I create in PHP and send back to my JavaScript. The problem is puzzling me. Here's the PHP code: header("content-type: text/json"); curl_setopt($ch,CURLOPT_URL, $url); curl_setop ...

Tailored design - Personalize interlocking elements

I am currently working on a custom theme and I am trying to adjust the font size of Menu items. In order to achieve this, I have identified the following elements in the tree: ul (MuiMenu-list) MuiListItem-root MuiListItemText-root If I want to modify th ...

Eliminate unnecessary CSS classes from libraries such as bootstrap when working on a React project

Our team is currently in the process of developing a React project that involves webpack and babel. Our goal is to automatically remove any unused CSS classes from CSS frameworks Bootstrap and AdminLTE 2, which are integral parts of our project. For this ...

Unlocking the power of namespaced Vuex getters in Mocha unit testing

I have been working on developing a new Vue component that utilizes a namespaced Vuex getter to retrieve a list of column names. The actual component is functioning properly and runs without any issues. During the Mocha unit testing phase, I set up a mock ...

The CSS selector functions as expected when used in a web browser, however, it

While conducting test automation using Selenium, I typically rely on css selectors to find elements. However, I recently came across a peculiar issue. I observed that in certain cases, the css selector works perfectly when tested in the browser console. Fo ...

Selecting the optimal data structure: weighing the benefits of using boolean check versus array .include (balancing performance and redundancy

My objects can have one or more properties assigned, with a total of 5 different properties in my case. To illustrate this, let's use a simple movie example where each movie can be assigned from 5 different genres. I have come up with two methods to ...

Looking to efficiently output information generated within a headless browser in node.js

Is there a way to print out data created inside a Node.js running headless browser if console.log('Text') isn't working? For example: const pup = require('puppeteer'); const chrom = await pup.launch({headless:'new'}); ...

Step-by-step guide to populating a JavaScript array with AJAX requests

Having some trouble with populating a JavaScript array using an Ajax request. Here is the code I'm working with. The Ajax portion seems to be running smoothly. function GetColumns() { var customArray = []; $.ajax({ url: '@Url.Con ...

Issue with reactivity in deeply nested objects not functioning as expected

Currently, I am utilizing Konvajs for my project. In simple terms, Konvajs provides a canvas for drawing and editing elements such as text nodes that can be manipulated by dragging and dropping. These nodes are organized within groups, which are then added ...

The environmental variable remains undefined even after it has been established

I've been experimenting with setting my environment variable in the package.json file so that I can access it in my server.js file. Despite trying NODE_ENV=development, set NODE_ENV=development, cross-env NODE_ENV=development, and export NODE_ENV=deve ...

jQuery struggles to locate the active class within the Bootstrap slider

Want to make some changes to the Bootstrap slider? Here is the HTML Code and jQuery: <div id="carousel-slider2" class="carousel slide bs-docs-carousel-example"> <ol class="carousel-indicators"> & ...