Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Render HTML from a json string in react

I'm trying to render an HTML object from a JSON string that I'm receiving from an API. I'm able to get the string to render to HTML successfully but it shows the entire JSON string. I'm only looking to get specific values (Phone, Name, Id.) What would be the best way for me to extract specific values from my JSON array and format it in HTML? I'm referring to records by state but I'm unable to get any sub-value of record in the render process.

Here is the JSON result rendered to HTML I'm getting when running the below code.

class menuScreen extends React.Component {

    constructor(props) {
        super(props)

        const data = store.getState();

        this.state = {



            username: '',
            messages: data.messages
        }
    }

    handleSearch(e) {
        this.setState({username: e.target.value})
    }

    handleChange(evt) {
        this.setState({
            username: evt.target.value.substr(0, 100)
        });

    }

    onLinkClicked() {

        var conn = new jsforce.Connection({serverUrl: 'https://cs63.salesforce.com', accessToken: sessionStorage.getItem('token')})

        var parent = this.state.username
        //console.log(this.state.username)
        conn.sobject("Contact").find({
            LastName: {
                $like: parent
            }
        }, 'Id, Name, Phone'

        ).sort('-CreatedDate Name').
        limit(5).skip(10).execute(function(err, records) {
            if (err) {
                return console.error(err);
            }
            for (var i = 0; i < records.length; i++) {
                var record = (records[i]);
                console.log("Name: " + record.Name); //these are the records I'm trying to render
               console.log("Phone: " + record.Phone);


            } this.setState({records : records})


        }.bind(this));

    }

    render() {
        return (
            <div className='menubox' id='menubox'>
                <div className='searchbar-container'>
                    <form onSubmit={e => e.preventDefault()}>
                        <input type='text' size='25' placeholder='Contact Last Name' onChange={this.handleChange.bind(this)} value={this.state.username}/>
                        <button type='submit' onClick={this.onLinkClicked.bind(this)}>
                            Search
                        </button>
                    </form>
                   </div>
                <div>
            <div dangerouslySetInnerHTML={ { __html: JSON.stringify(this.state.records) } }></div> //how can I show specific values, isntead of the entire string?
        </div>
    </div>
        )
    }
}
export default menuScreen;
like image 602
sortinousn Avatar asked Apr 10 '17 15:04

sortinousn


3 Answers

JSON.parse your string into a JavaScript object. You can then do whatever processing you want on that object, such as removing fields you don't want, and then you can JSON.stringify it back into a JSON string which you can render.

Something like:

class BlahBlah extends React.Component {
  constructor() {
    //...some code...
    this.processJson = this.processJson.bind(this)
  }
  //...a lot of code...    
  processJson(json) {
    var object = JSON.parse(json)
    var output = {}
    //for every property you want
    output[property] = object[property]
    return JSON.stringify(output)
  }
  //...a lot more code...
  render() {
    return(
      //...even more code...
      <div dangerouslySetInnerHTML={ { __html: this.processJson(this.state.records) } }></div>
      //...and yet more code.
    )
  }
}
like image 168
Pedro Castilho Avatar answered Nov 01 '22 20:11

Pedro Castilho


You can run a map function and output the JSX for each item.

class menuScreen extends React.Component {

    constructor(props) {
        super(props)

        const data = store.getState();

        this.state = {
            username: '',
            messages: data.messages,
            records: [],
        };
    }

    render() {
        return (
            <div>
                {this.state.records.map(record => (
                    <div>{record.attributes.name} {record.attributes.phone} {record.whatever}</div>
                )}
            </div>
        );
    }
}

Keep in mind, if you want a more complex HTML structure within map function, you'll have to wrap it in a single DOM node.

The full file would look like:

render() {
    return (
        <div className='menubox' id='menubox'>
            <div className='searchbar-container'>
                <form onSubmit={e => e.preventDefault()}>
                    <input type='text' size='25' placeholder='Contact Last Name' onChange={this.handleChange.bind(this)} value={this.state.username}/>
                    <button type='submit' onClick={this.onLinkClicked.bind(this)}>
                        Search
                    </button>
                </form>
            </div>
            <div>
                {this.state.records.map(record => (
                    <div>{record.attributes.name} {record.attributes.phone}</div>
                )}
            </div>
        </div>
    );
}
like image 25
Christian Hain Avatar answered Nov 01 '22 21:11

Christian Hain


You could create a separate render method that will render your records like so:

renderRecords(records) {
  return records.map(r => <div> r.Name, r.Phone</div>);
}

And then call the method inside your render method, instead of using dangerouslySetInnerHTML, like so

render() {
    return (
        <div className='menubox' id='menubox'>
            <div className='searchbar-container'>
                <form onSubmit={e => e.preventDefault()}>
                    <input type='text' size='25' placeholder='Contact Last Name' onChange={this.handleChange.bind(this)} value={this.state.username}/>
                    <button type='submit' onClick={this.onLinkClicked.bind(this)}>
                        Search
                    </button>
                </form>
               </div>
            <div>
        <div>{ this.renderRecords() }</div> 
    </div>
</div>
    )
}
like image 43
Mμ. Avatar answered Nov 01 '22 20:11

Mμ.