shorif2000
shorif2000

Reputation: 2654

how to return a string from map using reactjs

i have map function which i want to return html string and join to another string and display on modal. i am passing it through function params. The map seems to return array of objects and i am unsure how to convert this to string

    let found = [];
found.push({source:'x',destination:'x',protocol:'x',ports:'x'});
found.push({source:'y',destination:'y',protocol:'y',ports:'y'});
let flows = found.map(function(name, index){
    return <li  key={index.toString()} >{name.source.toString()} {name.destination.toString()} {name.protocol.toString()} {name.ports.toString()}</li>
}).reduce((prev, curr) => [prev, ', ', curr]);

showConfirm('',`You are about to approve a local market exemption. Click to confirm! <ul>${flows}</ul>`,()=>{submitApprove(args);self.props.clearModal()},()=>self.props.clearModal(),confirmOptions);

showConfirm open the following modal

    class ModalConfirm extends Component {
        ...

        render() {
            let yesDisabled = false;
            let yesText = 'Yes';
            let noDisabled = false;
            let noText = 'No';

            if (typeof this.props.modals.confirmOptions !== 'undefined') {
                yesDisabled = (typeof this.props.modals.confirmOptions.confirmYesDisabled !== 'undefined') ? this.props.modals.confirmOptions.confirmYesDisabled : false;
                yesText = (typeof this.props.modals.confirmOptions.confirmYesText !== 'undefined') ? this.props.modals.confirmOptions.confirmYesText : 'Yes';
                noDisabled = (typeof this.props.modals.confirmOptions.confirmNoDisabled !== 'undefined') ? this.props.modals.confirmOptions.confirmNoDisabled : false;
                noText = (typeof this.props.modals.confirmOptions.confirmNoText !== 'undefined') ? this.props.modals.confirmOptions.confirmNoText : 'No';
            }

            let bodyWrapper = 'Are you sure you want to confirm?';
            if (typeof this.props.modals.confirmMsg === 'string') {
                if (this.props.modals.confirmMsg.length > 0 || this.props.modals.confirmMsg !== null) {
                   bodyWrapper = Parser(this.props.modals.confirmMsg);
                }
                bodyWrapper = <div className="row-fluid" style={{ wordWrap: 'break-word' }} dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(bodyWrapper) }} />;
            }

            return (
                <Modal id="myModalReduxConfirm" className="modal fade" role="dialog" show={this.props.modals.showConfirm}>
                    {this.renderTitle()}
                    <Modal.Body>
                        {bodyWrapper}
                    </Modal.Body>
                    <Modal.Footer>
                        <Button bsClass="btn btn-success btn-sm" onClick={this.props.handleConfirmYes} disabled={yesDisabled}>{yesText}</Button>
                        <Button bsClass="btn btn-default btn-sm" onClick={this.props.handleConfirmNo} disabled={noDisabled}>{noText}</Button>
                    </Modal.Footer>
                </Modal>
            );
        }
    }
...

result

You are about to approve . Click to confirm! <ul>[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object]</ul>

UPDATE

i changed to the following now it does not pass string but just displays object.

self.props.showConfirm('',() => flows,()=>{submitApprove(args);self.props.clearModal()},()=>self.props.clearModal(),confirmOptions);

console.log(this.props.modals.confirmMsg());

displays

{store: undefined, title: "", body: ƒ, show: true, handleConfirmYes: ƒ, …}body: ƒ ()clearModal: ƒ ()confirmOptions: {confirmYesText: "Confirm", confirmYesDisabled: false, confirmNoText: "Cancel", confirmNoDisabled: false}handleConfirmNo: ƒ ()handleConfirmYes: ƒ ()modals: {showConfirm: true, confirmTitle: "", confirmMsg: ƒ, handleConfirmYes: ƒ, handleConfirmNo: ƒ, …}show: truestore: undefinedtitle: ""__proto__: Object
main.bundle.js:200439 
[object Object][object Object][object Object][object Object][object Object][object Object]

You can see the body shows f and when i log it, it does not interpret the object

Upvotes: 0

Views: 9091

Answers (2)

Baby Step
Baby Step

Reputation: 1

Assume if I have found1, found2 and found3, based on the clicked button change I switch and map to loop the structure?

const found1 = [
{
    name: {
        source: "eirglerk",
        destination: "zlekjrnzi"
    }
},
{
    name: {
        source: "lkcyukyuk",
        destination: "uylcl"
    }
},
{
    name: {
        source: "trutrurt",
        destination: "culcul"
    }
}
]

const found2 = [
    {
        name: {
            source: "eirglerk",
            destination: "zlekjrnzi"
        }
    },
    {
        name: {
            source: "lkcyukyuk",
            destination: "uylcl"
        }
    },
    {
        name: {
            source: "trutrurt",
            destination: "culcul"
        }
    }
]

var foundtype = "found1"

JSON.foundtype.map(() => { 
//Load found1 data
}

Upvotes: 0

Treycos
Treycos

Reputation: 7492

Your JSX elements cannot be rendered in arrays that mixes them with strings. And using reduce with JSX will often lead to headaches.

A quick solution to your problem would be to map your array directly and check if the element is not the last of the array to add the , :

const found = [
    {
        name: {
            source: "eirglerk",
            destination: "zlekjrnzi"
        }
    },
    {
        name: {
            source: "lkcyukyuk",
            destination: "uylcl"
        }
    },
    {
        name: {
            source: "trutrurt",
            destination: "culcul"
        }
    }
]

const App = props => (
    <p>
        You are about to approve . Click to confirm!
        <ul>
            {found.map(({ name, index }, i) => 
                <li key={index}> {name.source} {name.destination} {name.protocol} {name.ports}{i !== found.length - 1 && ','}</li>
            )}
        </ul>
    </p>
)


ReactDOM.render(<App/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.5.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.5.2/umd/react-dom.production.min.js"></script>
<div id='root'>

Or by keeping your code, you can do the following if you encapsulter the comma into a JSX element :

const found = [
    {
        name: {
            source: "eirglerk",
            destination: "zlekjrnzi"
        }
    },
    {
        name: {
            source: "lkcyukyuk",
            destination: "uylcl"
        }
    },
    {
        name: {
            source: "trutrurt",
            destination: "culcul"
        }
    }
]

const App = props => (
    <p>
        You are about to approve . Click to confirm!
        <ul>
            {found
                .map(({ name, index }) => <li key={index}> {name.source} {name.destination} {name.protocol} {name.ports}</li>)
                .reduce((prev, elem) => [prev, <span>,</span>, elem])}
        </ul>
    </p>
)


ReactDOM.render(<App/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.5.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.5.2/umd/react-dom.production.min.js"></script>
<div id='root'>

You will need to ass some CSS to keep your commas inline though

Upvotes: 2

Related Questions