Utilize a unique method of accessing objects through a combination of an object along with two specific

I am looking to create a function that combines an object, a path in a variable, and another path, similar to what is described in this StackOverflow post, but with 3 different components.

Here is a simple example to illustrate my goal: I want the combine() function to output either

selector[0].children[foo].textContent
or
selector[0].children[foo].children[0].textContent
based on the value of the bar variable.

const selector = document.getElementsByClassName('main')
const foo = 0
let bar = ''

const toggle = () => {
  if (bar === '') bar = '.children[0]'
  else bar = ''
}

const test = () => {
  console.log(combine('selector[0].children[foo]', bar, '.textContent'))
}
<div class='main'>
  <h1>Hello<span>world</span></h1>
  <button onclick='toggle()'>toggle</button>
  <button onclick='test()'>test</button>
</div>

I have a class that returns multiple properties (10) that are similar. The constructor takes a value that can determine something akin to the bar variable in the example above. By simply adjusting this value, each property can produce the desired result. I am seeking a solution that allows for switching between different scenarios without the need for extensive switch cases to handle each situation separately, thus reducing code duplication.

Answer №1

Is this what you were looking for? Make sure to educate yourself on the risks of using eval() before implementing it in your code: call javascript object method with a variable

const selector = document.getElementsByClassName('main')
const foo = 0
let bar = ''

const toggle = () => {
  if (bar === '') bar = '.children[0]'
  else bar = ''
}

function combine(){
let result = "selector[0].children[foo]"+bar+".textContent"
return result
}

const test = () => {
  console.log(eval(combine()))
  //I want a function like combine() that will print 'selector[0].children[foo].textContent' or 'selector[0].children[foo].children[0].textContent' depending on bar value.
}
<div class='main'>
  <h1>Hello<span>world</span></h1>
  <button onclick='toggle()'>toggle</button>
  <button onclick='test()'>test</button>
</div>

For a safer alternative, consider using this approach:

const selector = document.getElementsByClassName('main')
const foo = 0
let bar = ''

const toggle = () => {
  if (bar === '') bar = '.children[0]'
  else bar = ''
}

function combine(){
return Function('"use strict";return (selector[0].children[foo]'+bar+'.textContent)')()
}

const test = () => {
  console.log(combine())

}
<div class='main'>
  <h1>Hello<span>world</span></h1>
  <button onclick='toggle()'>toggle</button>
  <button onclick='test()'>test</button>
</div>

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#never_use_eval

Answer №2

If you're searching for a specific element, make sure to utilize the querySelector method.

Learn more about querySelector and querySelectorAll for a deeper understanding.

Avoid using eval as it can pose risks.

Take a look at my proposed solution below.

const selector = document.getElementsByClassName('main')
const path = ":nth-child(1)"

function getText(s, p) {
  if (s.length) // Is array
     return Array.from(s).map(x=> x.querySelector(p)?.textContent ?? "").join(" ");
  return  s.querySelector(p)?.textContent;
}

console.log(getText(selector, path))
<div class='main'>
  <h1>Hello<span>world</span></h1>
  <button onclick='toggle()'>toggle</button>
  <button onclick='test()'>test</button>
</div>

Answer №3

After our exchange in the comments, I have devised a method that requires three inputs and dynamically retrieves the specified property from the selected element. Additionally, if you provide the depth as the number of children, the property will be fetched from that specific child.

Illustration

Given:

The necessity to input a CSS selector The index of the child element or leave it blank The name of the property for the desired value

When:

You apply these three parameters to a function

Then:

The function will yield the value of the specified property from the chosen child by its position, if indicated, within the designated element using the selector.

Click to execute the test

// DISCLAIMER: For demonstration purposes only - lacks error handling

function getValueFromDOM(selector, child, prop) {
  if (!child) {
    return document.querySelector(`${selector}`)[prop];
  } 
  return document.querySelector(`${selector}`).querySelector(`:nth-child(${child})`)[prop];
}

var children = [1, 2, 3, 4];
var output = document.getElementById('output');

function test() {
  children.forEach(child => {
    const value = getValueFromDOM('.main', child, 'textContent');
    output.innerHTML += `<p>${value}</p>`;
  });
  // With empty second argument - will print 'main'
  output.innerHTML += getValueFromDOM('.main', '', 'className')

}

document.querySelector('button:last-of-type').addEventListener('click', test);
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>

<body>

  <div class='main'>
    <h4>Hello<span>world</span></h4>
    <button>toggle</button>
    <button>test</button>
    <div>Four</div>
    <div>Five</div>
    <div>Six</div>
  </div>
  <h3>Output:</h3>
  <div id="output"></div>
</body>

</html>

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

The Interface in TypeScript will not function properly when used on a variable (Object) that has been declared with the value returned from a function

I am currently in the process of developing an application using Ionic v3. Strangely, I am encountering issues with my interface when trying to assign a variable value returned by a function. Here is an example that works without any problems: export int ...

Best method to determine if three points in time are less than thirty minutes apart

In the form, there are 3 date/time input boxes with a requirement that the user cannot select times within half an hour of each other. I successfully converted all values to epoch format using a Javascript version of strtotime. However, I am unsure how to ...

Data sent through AJAX messaging is not being acknowledged

I recently made an AJAX request and set it up like this: $.ajax({ data : { id : 25 }, dataType : 'json', contentType : 'application/json; charset=utf-8', type : 'POST', // the rest of the ...

When selecting an option triggers a pop-up in JavaScript

Implementing javascript and HTML. Consider this example: <select name='test' > <option value='1'> <option value='2'> <option value='3'> </select> If the user selects optio ...

Issue with state not being reflected accurately

I am attempting to retrieve images from my Firebase storage using the following code: const [images, setImages] = useState([]); useEffect(() => { function list() { const storage = getStorage(); const imagesRef = ref(storage, "tes ...

Navigate divs with varying z-index values

I want to change the z-index of 3 divs by toggling them using jQuery, but I'm not sure how to do it. What I want is to click a button that relates to a specific div and increase the z-index of that div so the content inside it is shown. Currently, all ...

Updating values using events within a v-for loop in a Vue template: A step-by-step guide

Just starting out with Vue and Laravel! Currently, I am retrieving data from an API Resource in Laravel. The API consists of 2 fields: Goal Value Here is the code snippet: <template> <div class="container"> <h1> Progress ...

Implementing a Timer on a Bootstrap Progress Bar Using JavaScript

I am currently working on a timer with a progress bar. The timer itself is functioning properly, but I am facing an issue with syncing the progress bar with the timer. I am utilizing the bootstrap progress bar for this project. If I remove the 'bar&ap ...

Guide on how to append input field data to a table using jQuery

My current project involves working with a table, and I have encountered some challenges along the way. Typically, I have 4 input fields where I can input data that is then sent to the table in my view. However, if I exceed 4 values and need to add more, I ...

The collapsible tree nodes overlap one another in the D3.js visualization

I'm currently working on integrating a d3 code into Power BI for creating a collapsible tree structure. Each node in the tree is represented by a rectangular box, but I've run into an issue where nodes overlap when their size is large. Below is t ...

Retrieve a Play Scala variable in the $scope of an AngularJS application

After trying various methods recommended on StackOverflow, I am still struggling to retrieve a Play Scala variable within my Javascript $scope. The line of initialization in an HTML file is as follows: @(playVariable: String)(implicit request: play.api.mv ...

When an AJAX request is made, it can either return an array or a single object, potentially leading to

My proficiency in Javascript is definitely lacking, and I've only just begun to understand it. I have set up an AJAX call to an API using the GET method. The JSON data returned by the API is pretty standard. If I don't include an ID, I receive ...

Tips for creating a typescript typeguard function for function types

export const isFunction = (obj: unknown): obj is Function => obj instanceof Function; export const isString = (obj: unknown): obj is string => Object.prototype.toString.call(obj) === "[object String]"; I need to create an isFunction method ...

What is the mechanism behind making a Promise appear synchronous when using a Proxy in JavaScript?

const handler: ProxyHandler<any> = { get: (target: Promise<any>, prop: string, receiver: any) => { return target.then((o) => { return o[prop].apply(o); }); }, }; return new Proxy(obj, handler) ...

Issue encountered while attempting to pass a function within the data in React

I've encountered an issue while trying to pass a function called sectionOne and then calling it from another component. The error message I received is quite confusing. Error: Warning: Functions are not valid as a React child. This may happen if you r ...

`Generating and refreshing data on a uniquely structured grid using JQuery and AJAX`

I have an unusual grid structure with columns of varying heights. Column 1 may contain 4 squares to fill, column 2 may have 5, and column 3 may have 2. For the purpose of this inquiry, let's assume these values are static as follows: Col | Height ...

Is it possible to use Markdown in JavaScript without needing to enclose it in <p>

Is there a way to convert markdown text to HTML using JS libraries like markdown-js or marked without wrapping it in paragraph tags? For instance, I want to change this *italic* text to this <i>italic</i> text without including it within <p ...

Transmitting client-side Javascript data to backend server using Express

I am trying to fetch data from my frontend using the DOM and send it to the backend through Express but I'm unsure of how to proceed. I have used a POST method to console.log the data, but now I need help retrieving it in my Express backend. (The cons ...

Executing functions in a pre-defined order with AngularJS: A step-by-step guide

In my AngularJS Controller, I have a receiver set up like this: // Broadcast Receiver $rootScope.$on('setPlayListEvent', function(event, playListData) { if($scope.someSoundsArePlaying === true) { $scope.stopAllS ...

Sequencing Exponential Numbers in the Real Number System

In my R code, I am working with various strings that contain functions. For example: function <- "2x^{2}+6x^{5}+x^{4}+2". My goal is to reorder the output based on the exponents in descending order, so it would look like this: "6x^{5}+x^{4}+2x^{2}+2" O ...