2

I want to print this out on the web.

[Mandatory] By creating an account, you agree to ArticleA, ArticleB, ArticleC, ... ArticleX.

Where Link is a component from material-ui.

const createTACLine = (article, isMandatory) => {
  let cline = '';

  if (isMandatory) {
    cline = cline + '[Mandatory] By creating an account, you agree to ';
  }
  Object.keys(article).forEach(function (key) {

    cline = cline +  <Link
        component="button"
        variant="body2"
        to="/"
    > +{article[key].name}+ </Link>;
    if (parseInt(key) !== article.length - 1) {
      cline = cline + ', ';
    }

  });

  cline = cline + ".";

  return cline;
};

where article here is

{
    "id": 12,
    "name": "ArticleA",
    "url": "http://.....",
},
{
    "id": 13,
    "name": "ArticleB",
    "url": "http://.....",
},
{
    "id": 13,
    "name": "ArticleC",
    "url": "http://.....",
},
{
    "id": 14,
    "name": "ArticleX",
    "url": "http://.....",
}

Instead, I get the following.

[Mandatory] By creating an account, you agree to [object Object], [object Object], [object Object], [object Object].

I see a lot of examples using push to push list items but I need to build a sentence here. Is there some other way to build a string using a loop and ?

SuperStar518
  • 2,814
  • 2
  • 20
  • 35
hinewwiner
  • 627
  • 13
  • 25

4 Answers4

2

Try this instead:

  createTACLine = (article, isMandatory) => {
    return (
      <div>
        {isMandatory ? "[Mandatory] By creating an account, you agree to " : ""}
        {article
          .map(art => {
            return (
              <Link component="button" variant="body2" to={art.url}>
                {art.name}
              </Link>
            );
          })
          .reduce((prev, curr) => [prev, ", ", curr])}
      </div>
    );
  };

Michael
  • 128
  • 6
  • Thanks it did the trick. I have a quick question. Chrome complains that "Each child in a list should have a unique "key" prop." so I added 'key={art.id}' in Link to make the warning go away. Is this because map function returns array and it somehow expects unique key? – hinewwiner Jul 22 '19 at 14:21
  • In React, all elements should have a unique key. This question provides a lot of information about keys: https://stackoverflow.com/questions/28329382/understanding-unique-keys-for-array-children-in-react-js – Michael Jul 24 '19 at 11:42
1

It looks like you're passing in an array to the string, but what you really need is to just extract the article name.

Here's a working sandbox: https://codesandbox.io/s/friendly-feather-ihoh4

Working code:

import React from "react";
import ReactDOM from "react-dom";
import Link from "@material-ui/core/Link";

import "./styles.css";

const article = [
  {
    id: 12,
    name: "ArticleA",
    url: "http://....."
  },
  {
    id: 13,
    name: "ArticleB",
    url: "http://....."
  },
  {
    id: 13,
    name: "ArticleC",
    url: "http://....."
  },
  {
    id: 14,
    name: "ArticleX",
    url: "http://....."
  }
];

class App extends React.Component {
  createTACLine = (article, isMandatory) => {
    let cline = "";

    if (isMandatory) {
      cline = cline + "[Mandatory] By creating an account, you agree to ";
    }

    article.forEach((art, index) => {
      if(index === 0){
        cline = cline + art.name
      } else {
        cline = cline + ", " + art.name
      }

    });

    return (
      <Link component="button" variant="body2" to="/">
        {cline}
      </Link>
    );
  };

  render() {
    return <div>{this.createTACLine(article, true)}</div>;
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Community
  • 1
  • 1
Chris Ngo
  • 15,460
  • 3
  • 23
  • 46
  • Thanks for the quick reply. However, this makes the whole line "[Mandatory] By creating an account, you agree to ArticleA, ArticleB, ArticleC, ... ArticleX." as one link. I want each article to link to its url based on url in the json. – hinewwiner Jul 22 '19 at 10:42
0

Here article seems to be an array of objects. Try

article.forEach(obj => {
 // your Link with obj.name
})
Aman Gupta
  • 1,764
  • 4
  • 30
  • 58
0

I generate my links for "pagger" using loop, look at this:

render()
    {
       
        var page = 7;//this.props.pagger.page ;
        var pages = 20;//this.props.pagger.pages ;

        var clickablePageLeft = [];
        var clickablePageRight = [];

      
            for(var k=page-10; k<page; k++)
            {
                if(k < 1) continue;
                clickablePageLeft.push(k);
            }
   
            for(var k=page+1; k<pages; k++)
            {
                if(k > page + 10 ) continue;
                clickablePageRight.push(k);
            }
          
      
        
      

        return (
            <div className='pagger'>               
                  <div className='pleft'>
                      {
                        clickablePageLeft.map(item => {
                            return <Link to={ /page= + item }> {item} </Link>
                        } )
                      }
                       {page} 
                      {
                        clickablePageRight.map(item => {
                            return <Link to={ /page= + item }> {item} </Link>
                        } )
                      }
                  </div>
                  <div className='pright'>
                         <div className='records'>10</div>
                         <div className='records'>50</div>
                         <div className='records records_selected'>100</div>
                         <div className='records'>1000</div>
                     </div>
            </div>
        )
    }
Blazej Kita
  • 99
  • 1
  • 1
  • 10