0

I have a JSON that is providing a source prop to a component that would use it to create an <img src={source} ... /> element. I have seen on stackoverflow here and here that I need to import the picture with template literals to use it, <img src={require(`${source}`)} alt={title}/> where source is a prop, title is a prop.

The code is pasted below for reference. Thank you for your patience and assistance!

app.js

  parseJson(){
   var data = require('./highlights.json');
   for (var i = 0; i < data.length; i++) {
    var obj = data[i];
    console.log("source: " + obj.src);
  }
   return data.map((obj, key) =>
    <Highlight source={obj.source} link={obj.href} title={obj.title} desc={obj.desc} key={obj.src}/>  // returns the components and passes in the appropriate props
     )
 }


  render() {
    return (
      <div className="App">
      <Menubar/>
      <div>
      <Profilepic onClick={this.toggleModal}/>
      </div>
      <div className = "HighlightsContainer">
      {this.parseJson()} // returns a bunch of components here
      </div>
      <UploadButton/>
      <UploadWindow show={this.state.uploadWindowOpen}/>

      <Modal show={this.state.isOpen}
      onClose={this.toggleModal}>
      <Signup/>
      </Modal>
      <PhotoViewer show={this.state.photoViewerOn}/>
      </div>
      );
  }

highlight.jsx

import React from 'react';
let Highlight = function statelessFunctionComponentClass(props) {
// the 4 props that are passed in 
  let source = props.source;
  let link = props.link;
  let title = props.title;
  let desc = props.desc;

  let style = {
    position: 'relative',
    width: '300px',
    height: '300px',
    background: 'blue',
    display: 'inline-block'
  };
//returns the component of an image button
  return (
    <button style = {style}>
    <a href={link}>
//the require statement is giving issue, without it buttons are created
//without require, with it i get the error described below.
    <img src={require(`${source}`)} alt={title}/>
    </a>
    <div id="highlight1-title">{title}</div>
    <div id="highlight1-desc">{desc}</div>
    </button>
    );
};

export default Highlight;

the error - this error was fixed by changing to obj.src Error: Cannot find module 'undefined'.

  16 | return (
  17 |   <button style = {style}>
  18 |   <a href={link}>
> 19 |   <img src={require(`${source}`)} alt={title}/>
  20 |   </a>
  21 |   <div id="highlight1-title">{title}</div>
  22 |   <div id="highlight1-desc">{desc}</div>

** new module error **

Error: Cannot find module 'highlights/1.jpg'.
statelessFunctionComponentClass
C:/Users/auser/Documents/.../src/Component/Highlight.jsx:19

  16 | return (
  17 |   <button style = {style}>
  18 |   <a href={link}>
> 19 |   <img src={require(`${source}`)} alt={title}/>
  20 |   </a>
  21 |   <div id="highlight1-title">{title}</div>
  22 |   <div id="highlight1-desc">{desc}</div>
user539820
  • 33
  • 7
  • I have deleted my answer, as some Googling did point to the require method. I havent used it in React, but I've only started a few months ago, so maybe it's a recent thing :) – Martijn Jun 17 '18 at 21:12
  • sure, no problem! Was confused why the comment was gone. Have a good night! – user539820 Jun 17 '18 at 21:15

1 Answers1

0

I think there are other problems to your approach, but the reason you're getting this error is because of this line:

<Highlight source={obj.source} link={obj.href} title={obj.title} desc={obj.desc} key={obj.src}/>  // returns the components and passes in the appropriate props

You pass in obj.source as the value of the source prop, but from the code preceding it looks like you meant to put obj.src.

Duncan Thacker
  • 5,073
  • 1
  • 10
  • 20
  • Thank you, Duncan! That's what I get for naming these things similar yet different. I am now running into a separate issue. (editing the main post) – user539820 Jun 17 '18 at 21:29
  • also, do you mind elaborating a bit more about potential issues with this approach? I'm completely new to react and this is what I could come up with so far - your insight would be highly appreciated. – user539820 Jun 17 '18 at 21:35
  • Sure - it's mostly to do with `require()`. It's not really a command you can execute in a browser, it's an instruction to the compiler (e.g. webpack) to include a file into a larger application bundle. Trying to call `require()` with a variable means that webpack (or browserify, or whatever) can't work out which file you want, because the variable doesn't have a value until the program runs. (Note this isn't true if you're writing server-side code in NodeJS, but I suspect that's not what you're doing). – Duncan Thacker Jun 17 '18 at 21:43
  • P.S. If `source` is a string, `\`${source}\`` is exactly the same as `source`, so the template literal thing isn't really helping you at all. – Duncan Thacker Jun 17 '18 at 21:45
  • Thank you Duncan (re: template literal). But I will do some more reading about the problem with require() usage in this case. – user539820 Jun 17 '18 at 21:53
  • for any learners coming to visit in the future, i ended up creating a public folder, and the images are now loading with where source is the prop being passed in from the parent (which is parsed from the JSON file). Until I eventually try my hand at nodeJS, this will do for now. – user539820 Jun 17 '18 at 23:24