3

Here is now all of my code:


import styles from './Add.module.scss';
import { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import {IonPage, IonGrid, IonCol, IonRow, IonCardSubtitle, IonCard} from '@ionic/react';
import { Link } from 'react-router-dom';


const CategoryPage = () => {
  const {category} = useParams();
  const [loading, setLoading] = useState(true);
  const [loading2, setLoading2] = useState(true);
  const [categoryinfo, setCategoryinfo] = useState('');
  const [categoryname, setCategoryname] = useState('');

  useEffect(() => {
    const showjokes = ({category}) => {
      try {
        fetch(`https://fakeurl.herokuapp.com/categorypage/${category}/`, {
          method: 'GET',
          mode: 'cors',
          headers: {
            'Content-Type': 'application/json',
          },
        })
          .then(res => res.json())

          .then(data => {
            console.log('chisora', JSON.parse(data.jokes));
            setLoading2(false);
            const categoryjokes = JSON.parse(data.jokes);
            console.log('categoryjokes', categoryjokes);
            setCategoryinfo(categoryjokes);
            console.log(JSON.parse(data.jokes), '<==== here is data');
            getcatname({category});
          });
      } catch (error) {
        console.log('update, error time!', error);
        return false;
      }
    };
    showjokes({category});

    const getcatname = ({category}) => {
      try {
        fetch(`https://fakeurl.herokuapp.com/getcatname/${category}/`, {
          method: 'GET',
          mode: 'cors',
          headers: {
            'Content-Type': 'application/json',
          },
        })
          .then(res2 => res2.json())

          .then(data2 => {
            console.log('parker', JSON.parse(data2.categoryname));
            const categorynombre = JSON.parse(data2.categoryname);
            console.log('categorynombre', categorynombre.category);
            setCategoryname(categorynombre.category);
            setLoading(false);
            //console.log(JSON.parse(data.categoryname), "<==== here is data")
          });
      } catch (error) {
        console.log('update, error time!', error);
        return false;
      }
    };
  }, []);

  console.log('checking loading', loading, loading2);
  //console.log("the stuff",categoryinfo[0].joke_category)
  const stuff = categoryinfo;
  console.log('stuff', stuff);
  console.log('categoryname', categoryname);
  if (loading2 || loading) return <p>loading</p>;

  return (
    <IonPage>
      <h1>{categoryname} jokes</h1>
      <IonGrid className={styles.bottomContainer}>
        <IonRow>
          <IonCol size="12" className="ion-padding-start">
            <IonCardSubtitle className={styles.heading}>
              {categoryname} jokes
            </IonCardSubtitle>
          </IonCol>
        </IonRow>
        <div className={ styles.recentNotes }>

            { stuff.map((note, index) => {

                return (
                                

            <IonRow key={ `note_${ index }` } className="animate__animated animate__faster" id={ `noteRow_${ note.id }` }>
                <IonCol size="12">
                        <Link to={`/Update/${note.id}`}>
                                            <h2>{note}</h2>
                        </Link>
                </IonCol>
            </IonRow>
                            );
                        })}
        </div>

      </IonGrid>
    </IonPage>
  );
};

export default CategoryPage;

As you can see there are two functions in the useEffect: one to get an array of joke data and the other to get the name of the category the joke is in.

This is my error message:

Error: Objects are not valid as a React child (found: object with keys {joke, joke_name, joke_owner, joke_category, id}). If you meant to render a collection of children, use an array instead.

And it points to setLoading(false) within the getcatname function. The object that is referred to in the error is referring to the object that I get from the showjokes function.

The console.logs right before I check the two loading hooks log the data just perfectly. In other words, the functions in the useEffect do their job as far as the end product is concerned.

There is a lot I don't understand here. What is the "React child" that is being referred to? When I look around for solutions it seems to come up in render functions, but my error is simply pointing to the setLoading hook part. Why am I getting an error that seems to be referencing what is going on in another function but the error is within the other function?

Edit: Straight from postman:

data =

{
    "jokes": "[{\"joke_name\": \"scar lengthening\", \"joke_owner\": 1, \"id\": 5, \"joke_category\": 5, \"joke\": \"eventually scar tissue lengthens when they get tired of being pulled\"}, {\"joke_name\": \"bummer\", \"joke_owner\": 1, \"id\": 45, \"joke_category\": 5, \"joke\": \"Scar Tissue is a bummer\"}]"
}

data2 =

{
    "categoryname": "{\"category_owner\": 1, \"id\": 5, \"category\": \"scar tissue\"}"
}
11
  • I formatted your code (using Prettier) to make it easier for others to read. I had to add a few closing tags to your return JSX for the parser to accept it. Please review the last edit (#3) to make sure it's correct. Commented Dec 22, 2021 at 23:56
  • @jsejcksn looks good to me. I really need to work on making my code look more normal! Thanks! Commented Dec 22, 2021 at 23:58
  • So React is complaining as you are trying to render an Object (it doesnt know how to do this). It looks like the Objet it is trying render is the state categoryinfo. You turn categoryinfo into stuff when you do const stuff = categoryinfo Neither of these variables apear in the return. It seems like some code is ommitted? Commented Dec 23, 2021 at 0:12
  • 1
    It appears that note is not a string, but an object. Can you also include in your question an example of what data and data2 look like? Commented Dec 23, 2021 at 0:26
  • 1
    @JackMcKayFletcher Stuff = imgur.com/a/wQs7ayW Commented Dec 23, 2021 at 0:38

4 Answers 4

5
+100

So because note is an object, you can not use it as a string, unless you transform it with JSON.stringify(note) to understand the problem. But actually, if you just want the joke inside the object, you can use note.joke to access it.

Like this:

  {stuff.map((note, index) => {
        return (
            <IonRow key={`note_${ index }`} className="animate__animated animate__faster" id={ `noteRow_${ note.id }` }>
                <IonCol size="12">
                    <Link to={`/Update/${note.id}`}>
                         <h2>{note.joke}</h2>
                    </Link>
                </IonCol>
            </IonRow>
         );
  })}

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

2 Comments

worked! any particular reason why setLoading seemed to be pointed to in all of my errors? No matter where I put it. It would point to it.
@filifunk happy to hear that! Sorry, I do not the reason for that last question. Cheers.
0

Ah I see the bug now :). You have a bug in the map function:

stuff.map((note, index)....

index here is not the index of the list as you expect - rather it is another element of the list stuff. This is an object which you are rendering in full. This is why you are seeing the error about rendering an object.

your map function should just take 1 arguement. You can then get index of that element as such:

stuff.map((note) => {
   const index = stuff.indexOf(note)

})

Comments

0

In this part of your component's JSX:

stuff.map((note, index) => {
  //...
})

you have nested within the <Link> an <h2>:

<h2>{note}</h2>

This is the source of the problem. note here is one of the objects from the array in data.jokes from your API response.

You'll need to convert this into a string before using it as the content inside the <h2>. If you want just the joke, you can use

<h2>{note.joke}</h2>

or you can use the name of the joke:

<h2>{note.joke_name}</h2>

etc.

Comments

-1

I hope you imported IonPage, IonGrid, IonRow, IonCol, IonCard

1 Comment

I did import those yes

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.