1

Here is the code that I've wrote. Say there is a sentence "Hello, please follow us as @followme". What this function will do is find the word that contains the "@" then return the sentence again although the @ will then be linked. If i was join this array using .join(" ") the JSX element will display as [object, object] so as a fix i've added a space to the array every other index.

My question is does this work? Have I missed something so simple that could make my life easier, would love to know! Thanks

---- As an edit, If i didn't add the extra spaces to the array or don't use .join, then the sentence is literally one word...

const getInstagram = props => {
  //Split sentence into an array
  let test = props.split("@" +1).pop().split(" ");
  let one;

//Get the word that contains @
  test.map(word => {
    if (word.includes("@")) {
      one = word;
    }
  });


  //Gets the array position
  let position = test.indexOf(one);
  test.splice(position);

  if (position >= 0) {
    let line = <a href={`https://instagram.com/${one}`}>{one}</a>
    test.splice(position,0,line)    
  }

  for(let i = 0; i < test.length; i++) {
    test.splice(i++,0, " ");
  }

    return (
      <p style={{ opacity: 1 }}>
      {test}
      {console.log(test)}
      </p>
    );  
 };
1
  • I'm sure there are going to be many alternative approaches that do what you're doing in another way (splitting on space, then adding the space back in in another loop, or in a loop at render time). I don't think there is going to be a cleaner approach. just my 2 cents. Commented Sep 25, 2019 at 20:19

1 Answer 1

2

Another approach the preserves the whitespaces of the input phrase, that allows "@anchors" to be extracted and wrapped in an <a> element would be to scan the input string via a for-loop and extract and wrap anchor substrings as they are encountered as follows:

function ExtractAnchors(phrase) {

  const parts = [];

  /* Iterate characters of phrase */
  for (let i = 0, j = 0; j < phrase.length; j++) {

    /* If character is "@", extract the anchor */
    if (phrase[j] === "@") {

      /* Add string from prior index to start of anchor */
      parts.push(phrase.substring(i, j));

      /* Find end-index of the anchor */
      let k = j;
      while (k < phrase.length && phrase[k] !== " ") {
        k++;
      }

      /* Extract the actual anchor substring from start and end indicies */
      const anchor = phrase.substring(j, k)
      parts.push(<a href={`https://instagram.com/${anchor}`}>{anchor}</a>);

      /* Update indicies to end of extracted anchor */
      j = k;
      i = k;

    } else if (j === phrase.length - 1) {
      if (i !== j) {
        /* Edge case to ensure whole string is collected if no anchor
        or chracters exist after an anchor */
        parts.push(phrase.substring(i, j + 1));
      }
    }
  }

  return parts;
}

This could be used in the following way, of which all cases work as expected:

<div>
  <p>Plain string:</p>
  {ExtractAnchors("Follow us")}

  <p>String with whitespaces and single anchor:</p>
  {ExtractAnchors("Follow us at @foo now")}

  <p>String with whitespaces, multiple anchors, one at end of phrase:</p>
  {ExtractAnchors("Follow us at @foo now or @bar")}

  <p>String with whitespaces, multiple anchors, one at start of phrase:</p>
  {ExtractAnchors("@foo or @bar are good to follow")}

  <p>Empty string:</p>
  {ExtractAnchors("")}
</div>

Here's a working example - hope that helps!

Sign up to request clarification or add additional context in comments.

1 Comment

I was going to suggest a string building approach, but man that's a lot of work :D glad you posted this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.