-1

I am sending a raw HTML from node.js to react. and It was successful. However, when I try to render it, they are render as raw string as opposed to HTML elements

This is how I get the string from front-end:

 componentDidMount() {
    this.callApi()
      .then(res => this.setState({ data: res.express}))
      .catch(err => console.log(err));
  }

  callApi = async () => {
      const response = await fetch('/myCart');
      const body = await response.json();
      if (response.status !== 200) throw Error(body.message);

      return body;
  };

The render method from my react(Simplified) looks like this:

    render()  {
        return (
          <div>
            <div className="App">
              <header className="App-header">
                <img src={logo} className="App-logo" alt="logo" />
                <h1 className="App-title">Welcome to Shopping Center</h1>
              </header>
            </div>
            <div className="row">
              {this.state.data}
            </div>
        </div>
        <button type="button" className="btn btn-primary Bottom-right " onClick={(e) => this.handleSubmit(e)}>
              My Cart
        </button>
      </div>
    );
  }
}

In my server.js, i have the following code handeling the post request:

const express = require('express');
const app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());

//DB connections
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";



app.get('/myCart', (req, res) => {
  var data;
  var htmlString ="";
  var total = 0;

  MongoClient.connect(url, { useNewUrlParser: true }, function(err, db) {
    if (err) throw err;
    var dbo = db.db("cart");
    dbo.collection("items").find().toArray(function(err, result) {
      if (err) throw err;
      console.log("here")
      data = result
      for(let item of data){
        //console.log("desc: " + item.desc)
        //console.log("price: " + item.price)
        htmlString += "<div>" + item.desc + "</div>" + "<div>" + item.price + "</div>"
        total += item.price
      }
      console.log("total is" + total)
      htmlString +="<div>" + total + "</div>"
      console.log(htmlString)
      res.send({express: htmlString})
      db.close();
    });
  });
}); 

Why doesn't react render the string as an HTML elements, but rather a raw string?

Spencer Ovetsky
  • 170
  • 6
  • 14
  • 1
    possible duplicate: https://stackoverflow.com/questions/44643424/how-to-parse-html-to-react-component – Raghav Garg Sep 28 '18 at 13:36
  • 1
    you will have to parse the html string, using packages like this: https://www.npmjs.com/package/react-html-parser, https://www.npmjs.com/package/html-react-parser – Raghav Garg Sep 28 '18 at 13:37

2 Answers2

2

You may be able to leverage dangerouslySetInnerHtml, like so:

render()  {
  return (
    <div>
      <div>
        <div className="App">
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <h1 className="App-title">Welcome to Shopping Center</h1>
          </header>
        </div>

        <div 
          className="row"
          dangerouslySetInnerHTML={{__html: this.state.data}}
        />

      </div>
      <button 
        type="button"
        className="btn btn-primary Bottom-right " 
        onClick={(e) => this.handleSubmit(e)}
      >
        My Cart
      </button>
    </div>
  );
}
Ted
  • 14,757
  • 2
  • 41
  • 58
  • does ReactHtmlParser not recognize bootstrap attribute? Please check out my new question https://stackoverflow.com/questions/52558728/reactjs-invalid-dom-property-classname-error – Spencer Ovetsky Sep 28 '18 at 15:45
0

You could just wrap your string in the following, once it has been fetched.

document.createRange().createContextualFragment(yourString);
Tyler2P
  • 2,324
  • 26
  • 22
  • 31
Kaotik
  • 1