0

I have this webapp where user enters a paragraph and the backend scans the paragraph(s) and will send arrays of hard and very hard sentences. Now what I want to do is to show the entire paragraph with the hard and very hard sentences to be highlighted with a background color of yellow and red respectively while the sentences that are neither hard or very hard to be shown with just a default background color. At first, I thought it would be quite easy but the classes aren't even assigned to the arrays when it detects them. I tried to code it but it isn't showing the colors.

here's what I did so far:

class SomeComponent extends React.Component{
  this.state={
    hardArray: [],
    vhardArray: [],
    enteredText: "",
  }

  performHard = async () => {
    const { enteredText } = this.state;
    const body = { text: enteredText };
    const stringifiedBody = JSON.stringify(body);
    const options = {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json"
      },
      body: stringifiedBody
    };
    const url = "api/same";

    try {
      const response = await fetch(url, options);
      const result = await response.json();
      this.setState(prevState => ({
        hardArray: [...prevState.hardArray, ...result.hard]
      }));
    } catch (error) {
      console.error("error");
    }
  };

  performVHard = async () => {
    const { enteredText } = this.state;
    const body = { text: enteredText };
    const stringifiedBody = JSON.stringify(body);
    const options = {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json"
      },
      body: stringifiedBody
    };
    const url ="api/same";
    try {
      const response = await fetch(url, options);
      const result = await response.json();
      this.setState(prevState => ({
        vhardArray: [...prevState.vhardArray, ...result.very_hard]
      }));
    } catch (error) {
      console.error("error");
    }
  };

  performAnalysis = () => {
    this.performHard();
    this.performVHard();
  };

  render(){
    return(
        //some code
        <textarea
            name="enteredText"       
            className="textareaclass"
            placeholder="Enter your text here"
            onChange={this.handleChange}
            value={enteredText}
        ></textarea>
        <Button 
            className="rectangle-3" 
            onClick={this.performAnalysis}>Analyse
        </Button>
        <hr />
        <div>
            {
                enteredText.split(" ").map(word => {
                    if (this.state.vhardArray.includes(word)) {
                        return <span className="vhardColor">{word}</span>; //it didn't add these css classes
                    }

                    if (this.state.hardArray.includes(word)) {
                        return <span className="hardColor">{word}</span>;
                    }

                    return [word, " "];
                })
            }
        </div>
        //some code
    )
  }
}

This is suppose a paragraph that the user enters.

It's the possibility of having a dream come true that makes life interesting. He stepped down, trying not to look long at her, as if she were the sun, yet he saw her, like the sun, even without looking. I cannot fix on the hour, or the spot, or the look or the words, which laid the foundation. Satan trembles when he sees the weakest saint upon their knees

then this is how the response from the api would look like

{
  "hard": [
    "It's the possibility of having a dream come true that makes life interesting",
    "I cannot fix on the hour, or the spot, or the look or the words, which laid the foundation.",
  ]
 "very_hard": [
    “He stepped down, trying not to look long at her, as if she were the sun, yet he saw her, like the sun, even 
     without looking.”
  ],
"word_count": 132
}
Dinesh Nadimpalli
  • 1,441
  • 1
  • 13
  • 23
UbuntuNewb
  • 411
  • 4
  • 13
  • 1
    In my opinion your API has to few information. Split paragraph into sentences, but keep in your API info about order of sentences. Your API should look rather like entities: `{"word_count": 132, "sentences": [ { "content": "Your sentence.", "complexity": "hard", "orderID": 0, }, ]` so now you can simply iterate only once through one array and add sentences with correct color. You may want to sort the array first. – Zydnar Dec 15 '19 at 10:36
  • I didn't make the api so that's a problem. this is how I got the api as it is – UbuntuNewb Dec 15 '19 at 10:41
  • 1
    In this case I guess you need somehow get this order of sentences, because it would be the easiest, just map array of sentences into react element. Maybe split input paragraph into sentences, and just use `paragraphSplitedIntoSentences.indexOf(sentenceFromApi)` to get order of sentences. – Zydnar Dec 15 '19 at 10:47
  • @Zydnar so you're suggesting that I should split the paragraph into sentences and give each sentences index number myself in the frontend? to all the sentences or just the hard and very hard sentences?? – UbuntuNewb Dec 15 '19 at 10:57
  • 1
    1. Get your API response. 2. Split input paragraph into sentences to make second array. 3. Thanks to array from point 2. create other array of objects of this shape: `[ { "content": "Your sentence.", "complexity": "hard", "orderID": 0, }, ]` 4. Now, in render, just map array from point 3. `.map(({content, complexity})=>{content})` – Zydnar Dec 15 '19 at 11:03
  • I'm confused at point 2 and lost it at point 3. looks quite complicated. can you show it to me please? I'm quite new, don't have much experience with react or even javascript tbh. – UbuntuNewb Dec 15 '19 at 11:14

1 Answers1

3

Your api response is something like this

{
  "hard": [
    "It's the possibility of having a dream come true that makes life interesting",
    "I cannot fix on the hour, or the spot, or the look or the words, which laid the foundation.",
  ]
 "very_hard": [
    “He stepped down, trying not to look long at her, as if she were the sun, yet he saw her, like the sun, even 
     without looking.”
  ],
 "word_count": 132
}

where hard and very_hard are arrays which you are storing in the react state.

But when you are checking whether the enteredText you are checking each word. As your are using includes it will check whether the given word is there in the array or not

Example

let hard = [
    "It's the possibility of having a dream come true that makes life interesting",
    "I cannot fix on the hour, or the spot, or the look or the words, which laid the foundation.",
  ]
let word = "possibility"
// This is what you code is doing
hard.includes(word) //will return false as hard is an array

So, what you need to do is concatinate all the hard and very_hard arrays into a single strings and then do .includes(). It will work!

Dinesh Nadimpalli
  • 1,441
  • 1
  • 13
  • 23
  • yeah I figured it was due to this very reason but why do we need to concatenate when the api response is giving sentences anyway. isn't there anything to check sentences like "includes" for word or am I missing something? can you please show it to me how you would tweak my code to do what I wanted – UbuntuNewb Dec 15 '19 at 11:17
  • If the user enters sentences which end with fullstop ".", then you can use split to do the work. But, the thing is you cannot predict user's input. So, it is better if you can combine all the array elements into a string and then do .includes() on each word. – Dinesh Nadimpalli Dec 15 '19 at 11:27
  • you mean something like this? ```{enteredText.split(". ").map(word => { if (this.state.vhardArray.split(". ").includes(word)) { return {word}; }``` – UbuntuNewb Dec 15 '19 at 11:31
  • Your vhardArray is an array right? So, doing this should work ```{enteredText.split(". ").map(word => { if (this.state.vhardArray.includes(word)) { return {word}; }``` – Dinesh Nadimpalli Dec 15 '19 at 11:34
  • Can you share the ```enteredText and vhardArray``` which you used? – Dinesh Nadimpalli Dec 15 '19 at 11:39
  • can't we do something like this? https://stackoverflow.com/questions/4810841/how-can-i-pretty-print-json-using-javascript – UbuntuNewb Dec 15 '19 at 11:39
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/204292/discussion-between-ubuntunewb-and-dinesh-nadimpalli). – UbuntuNewb Dec 15 '19 at 11:39