0

I am working with an API and dynamically injecting the HTML from the JS file. In the HTML (that is written in the JS file), I need to run conditional but the conditional only works when it is outside of the template literal from the injected HTML. I thought perhaps I needed a script tag but when I use one, the code doesn't run and the image isn't rendered. If I remove the script tag, the "if"/"else" words are rendered, the image is rendered but the conditional isn't actually running. Below I have included a snip of the code I am trying to inject. How can I get the conditional to run?

const createNasaCard = (nasaItem) => {
  document.querySelector("#nasaInfo1").insertAdjacentHTML(
    "beforeend",
    `
    <section class="container my-5">
    <div class="row g-3">
        <div class="col-lg-6">
        
        <script> 
        if(${nasaItem.media_type} === "image"){
          <img src="${nasaItem.url}" alt="Nasa Image of the Day" class="w-100 h-60 shadow" >
        } else if(${nasaItem.media_type} === "video"){
          <iframe src="${nasaItem.url}" frameborder="0"></iframe>
        }
        </script>
            
        </div>

Image from dev tools

1 Answer 1

1

Consider (and, more importantly, observe in your debugging) what this produces:

if(${nasaItem.media_type} === "image")

If you're expecting the value of nasaItem.media_type to ever be the string "image" then what you have is:

if(image === "image")

Unless you have a variable called image, this will produce an error. If you're expecting the value to be a string, wrap it in quotes:

if("${nasaItem.media_type}" === "image")

Edit: Once that's corrected, the second problem is that this doesn't make sense:

if("image" === "image"){
  <img src="some_url_value" alt="Nasa Image of the Day" class="w-100 h-60 shadow" >
}

You can't just write HTML directly in the JavaScript code and expect that code to know what to do with it. Where in the DOM do you want to put that HTML code? For example, you're adding HTML to the DOM already with this operation:

document.querySelector("#nasaInfo1").insertAdjacentHTML("beforeend", "SOME HTML CODE");

This inserts the HTML in relation to the matched #nasaInfo1 element. That's how you'd add HTML to the DOM from JavaScript. So in the new JavaScript code you're adding... That's how you'd add HTML to the DOM.

Unless... What you actually meant was to invoke that JavaScript logic now as part of building the template literal. (Which is probably what you want, since dynamically adding JavaScript to the page is pretty strange and has a high potential for bugs.) In that case the logic needs to be in code, not part of the template literal string. Something like this:

`<section class="container my-5">
  <div class="row g-3">
    <div class="col-lg-6">
    ${
      nasaItem.media_type === "image" ?
      `<img src="${nasaItem.url}" alt="Nasa Image of the Day" class="w-100 h-60 shadow">` :
      nasaItem.media_type === "video" ?
      `<iframe src="${nasaItem.url}" frameborder="0"></iframe>` :
      ''
    }
    </div>
  </div>
</section>`

So within the overall ${} of the larger template literal there is essentially an inline conditional (chaining some ternary conditional operators) to produce a value. That value is conditionally one of a couple other template literals, depending on the value of nasaItem.media_type.

This overall template literal should resolve to something like:

<section class="container my-5">
  <div class="row g-3">
    <div class="col-lg-6">
      <img src="SOME_URL_VALUE" alt="Nasa Image of the Day" class="w-100 h-60 shadow">
    </div>
  </div>
</section>

You can nest the logic any way you like. But the logic needs to be part of the executing code, not part of a string. If it's part of the string then it will be added to the page like the rest of the string.

If the large template literal with inline conditions that add more template literals is getting unwiedly, you can always break it apart into multiple operations. For example:

let html = `
  <section class="container my-5">
    <div class="row g-3">
      <div class="col-lg-6">`;
if (nasaItem.media_type === "image") {
  html += `<img src="${nasaItem.url}" alt="Nasa Image of the Day" class="w-100 h-60 shadow">`;
} else if (nasaItem.media_type === "video") {
  html += `<iframe src="${nasaItem.url}" frameborder="0"></iframe>`;
}
html += `
      </div>
    </div>
  </section>`;
document.querySelector("#nasaInfo1").insertAdjacentHTML("beforeend", html);

I personally prefer the former. But there are a variety of ways one can organize one's code, including refactoring out small parts into their own aptly named functions to make the code more readable.

Any way you look at it, all you're doing is building a string. Don't over-complicate it by trying to put more code within that string and expecting it to execute. Just piece together the string however you need to.

Sign up to request clarification or add additional context in comments.

8 Comments

"image" is one of the values inside the API. The conditional works perfectly until it is added to the injected HTML. Adding additional template literals is only giving me syntax errors since the entire code is wrapped in a template literal. This code is written in my JS file, not the HTML file.
@TamiHughes: Don't add additional template literals. Just wrap the value in quotes. String values need to be wrapped in quotes in JavaScript. (And pretty much any language.) In your browser's debugging tools you can observe the result of your code when it's added to the DOM, and observe any errors it generates when using strings without quotes.
Adding quotes around the nasaItem.media_type doesn't work. Nothing is rendered
@TamiHughes: In your browser's debugging tools, in the DOM explorer, what is the resulting code that gets added to #nasaInfo1? Are there any errors on the browser's development console? Can you update the question to a runnable minimal reproducible example demonstrating the problem?
I checked and added an image from the dev tools. It should be posted in my original question
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.