Passing a value to insert into a template literal as a variable, is this possible?

Hi all. I always receive great help here, much appreciated :slight_smile:

So I’m trying to pass a variable into a function , that should then insert it into a literal template. Like so:

async function displayData(url,displayWhere,displayCurrent,displayPrevious){
	
	const data= await(getJson(url));
	//console.log(data);
	let stringDaily='',stringWeekly='';
	
	
		
	data.forEach((element,index) => {
		 const results= document.querySelector(displayWhere[index]);
	     stringDaily = `<h2>${element.title}</h2>
		        <p class='fs-1'>
				   ${displayCurrent}hrs             //this does not work.
				</p>
				<p>
				   ${element.timeframes.daily.previous}hrs
				</p>
				`
				
		 $(results).append(stringDaily);
    });
	
	
}

And I call this function so:

let currentDay = 'element.timeframes.daily.current';
	let previousDay= 'element.timeframes.daily.previous';
	displayData(url, displayWhere,currentDay,previousDay);

Now I know it passes it as a string, so maybe that’s problem? It becomes this?

${"element.timeframes.daily.previous"}hrs

How do I solve this and is this even possible?
Thanks

Well, yes. You’re just passing it a string, not a variable. Just do this?

<p class='fs-1'>${element.timeframes.daily.current}hrs</p>
<p>${element.timeframes.daily.previous}hrs</p>
1 Like

Thank you , but I have to be able to change from daily to weekly and monthly.
If I do it your way I’d have to hide the other values each time.
It seems easiest with the function. Is it possible some way?

I mean I would also be using:

let weeklyCurrent = ‘element.timeframes.weekly.current’;
let weeklyPrevious = ‘element.timeframes.weekly.previous’;
let monthlyCurrent= ‘element.timeframes.monthly.current’;
let monthlyPrevious=‘element.timeframes.monthly.previous’;

which I want to be able to pass into the displayCurrent and displayPrevious arguements:

displayData(url, displayWhere,weeklyCurrent, weeklyPrevious);
displayData(url,displayWhere, monthlyCurrent, monthlyPrevious);

I would actually just be using a single string in the function , so just

let string =‘’; instead of let stringDaily=‘’; let stringWeekly=‘’;
That way I wouldn’t have to worry about deleting anything.

Now I managed something to work somewhat, by reading this stackoverflow post:
https://stackoverflow.com/questions/30003353/can-es6-template-literals-be-substituted-at-runtime-or-reused

All the way towards the bottom, there’s this post:

//The short answer is just use _.template in lodash

// Use the ES template literal delimiter as an "interpolate" delimiter.
// Disable support by replacing the "interpolate" delimiter.
var compiled = _.template('hello ${ user }!');
compiled({ 'user': 'pebbles' });
// => 'hello pebbles!'

So I’m using iodash now and this code:

async function displayData(url,displayWhere,displayCurrent,displayPrevious){
	
	const data= await(getJson(url));
	//console.log(data);
	let string='';
	
	
		
	data.forEach((element,index) => {
		 const results= document.querySelector(displayWhere[index]);
	     string = _.template(`<h2>${element.title}</h2>
		        <p class='fs-1'>
				   ${displayCurrent.daily}hrs       
				</p>
				<p>
				   ${element.timeframes.daily.previous}hrs
				</p>
				`);
				
		 $(results).append(string);
    });
	
	
}

I call it so

displayData(url, displayWhere,{'daily': 'element.timeframes.daily.current'},previousDay);

I’m only trying this out for the the daily current element, previous can wait.
It prints element.timeframes.daily.current hrs on screen?

And having to use

  ${displayCurrent.daily}hrs    

in the displayData function defeats my whole purpose of switching for daily, weekly and monthly?
Hope someone is willing to help

Thanks

I would suggest you post the complete code, a repo would be nice.

Then explain exactly the requirements and what you are trying to achieve. Right now we really have no context and just code fragments.


_.template returns a function.

https://lodash.com/docs/4.17.15#template

Still not really sure why you need it as it is unclear to me what you are trying to achieve.

Thanks for the reply.
My page has 3 links, one for ‘daily’, one for ‘weekly’ and one for ‘monthly’.

A JSON file has all the data that will be displayed, this is one section:

{
    "title": "Play",
    "timeframes": {
      "daily": {
        "current": 1,
        "previous": 2
      },
      "weekly": {
        "current": 10,
        "previous": 8
      },
      "monthly": {
        "current": 23,
        "previous": 29
      }
    }
  },

So either ‘daily’ , ‘weekly’ or ‘monthly’ should be shown for ‘current’ and ‘previous’.
My displayData function should load this JSON data, either the ‘daily’ , ‘weekly’ , or ‘monthly’ data. On load it should load ‘daily’ , but doing that is easy.

I could write three different displayData functions instead : displayDaily() , displayWeekly() and displayMonthly() , but that seems overkill .

I 'm trying to update the ${JSON path } part to show either ‘daily’ , ‘weekly’ or ‘monthly’.

I’m trying to do this within my displayData funtion:
${element.timeframes.CHANGETHISVARIABLE.current}
${element.timeframes.CHANGETHISVARIABLE.previous}

CHANGETHISVARIABLE should then be either ‘daily’ , ‘weekly’ , or ‘monthly’ , depending on which link the user clicked.

I don’t have a repo yet, but if this isn’t clear enough I can set one up.
Thanks

It’s still very unclear why you’re trying to do this, afaics it’s so that you can avoid doing this:

Which isn’t a great idea, seems like you’re trying to abstract over something that’s very easy to write simply.

As it is, it’s fairly simple to do what you’re trying to do (although you end up with one complex function rather than three simple ones).

The key problem is that you’re using dot syntax for accessing objects. The dot syntax isn’t a string, it’s a set of variables (well, keys) chained with periods. {VARIABLE}.KEY.KEY.KEY.ETC

How else can you access object properties (HINT: this allows you access properties dynamically)?

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.