1

Based on this previous questions I made (Show fetch results in render return() in React.js), from which I received json results, I now need to count the number of sofas that each brand has. For example, Brand X has 2 occurences and Brand Y has 3043.
I get the brand from one sofa by calling myUrlApi + /couch-model on fetch and the json is something like what you can see in the picture below. enter image description here

Has you can see each sofa has associated to itself a brand. What I want to count is how many sofa each brand has.

I'll put my current code here:

export class Main extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      token: {},
      isLoaded: false,
      models: []
    };
  }

  componentDidMount() {
    /*code to generate token, not needed for the purpose of the question*/

    fetch(url + "/couch-model/?limit=9", {
      method: "GET",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json",
        Authorization: "JWT " + JSON.parse(localStorage.getItem("token")).token
      }
    })
      .then(res => {
        if (res.ok) {
          return res.json();
        } else {
          throw Error(res.statusText);
        }
      })
      .then(json => {
        this.setState(
          {
            models: json.results
          },
          () => {}
        );
      });
  }

  render() {
    const { isLoaded, models } = this.state;

    if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
      return (
        <div>
          {models.map(model => (
            <a href="/sofa" key={model.id}>
              <div className="Parcelas">
                <img src={img_src} className="ParcImage" alt="sofa" />
                <h1>Sofá {model.name}</h1>
                <h2>
                  1,200<span>€</span>
                </h2>

                <p
                  className="Features"
                  dangerouslySetInnerHTML={{ __html: model.description }}
                />

                <button className="Botao">
                  <p className="MostraDepois">Ver Detalhes</p>
                  <span>+</span>
                </button>
                <img
                  src="../../img/points.svg"
                  className="Decoration"
                  alt="points"
                />
              </div>
            </a>
          ))}
        </div>
      );
    }
  }
}

Hope I was clear, ask if you have any doubt.

2 Answers 2

1

Edit ojk8xwv22y

if your results look like this as you said in your post :

{
  results: [
    {
      brand: { name: "Brand-A", image: "", etc: "..." },
      category: "A",
      code: "AAA",
      name: "SofaA",
      price: 1200
    },
    {
      brand: { name: "Brand-A", image: "", etc: "..."  },
      category: "A",
      code: "AAA",
      name: "SofaB",
      price: 1200
    },
    {
      brand: { name: "Brand-B", image: "", etc: "..."  },
      category: "A",
      code: "AAA",
      name: "SofaC",
      price: 1200
    }
  ]
}

You can add a state property like sofasPerBrand initialized to {}

constructor(props) {
    super(props);
    this.state = {
      token: {},
      isLoaded: true,
      models: [],
      sofasPerBrand: {}
    };
  }

And add in the setState function in componentDidMount the RIYAJ KHAN reduce function like this :

this.setState(
      {
        models: json.results,
        sofasPerBrand: json.results.reduce((coundData, sofa, index) => {

          if (!!coundData[sofa.brand.name]) {
            coundData[sofa.brand.name] += 1;
          } else {
            coundData[sofa.brand.name] = 1;
          }
          return coundData;
        }, {})
      },
      () => { }
    );

then you can declare it in your render function :

const { isLoaded, models, sofasPerBrand } = this.state;

and use it like that any where :

<ul>
  {Object.keys(sofasPerBrand).map(brand=>(
      <li>{brand} : {sofasPerBrand[brand]}</li>
  ))}
</ul>
Sign up to request clarification or add additional context in comments.

15 Comments

Almost working and that's it! The setState can be outside the fetch, right? Because the results are being empty and saying Line 88: Expected to return a value in arrow function array-callback-return
When I gather sofasPerBrand with the previous fetch of brands, the brands stop showing
Different brands are getting the same numbers
can you share this on codesandbox or other tool like this ?
I made a little codesandbox to explain the "b" thing if you want :) codesandbox.io/s/4q683kwrxx
|
1

One can use javascript#reducers for it.

models.reduce((coundData,sofa,index)=>{

    if(!!coundData[sofa.brand.name]){
        coundData[sofa.brand.name] +=1; 
    }else{
        coundData[sofa.brand.name]=1;
    }

    return coundData;
}, {})

6 Comments

Its not redux,reducers is higher order function.
Yes, sorry I'm missunderstood, that's why I deleted the comment. I'll teste, thank you
Where should I put that @RIYAJ KHAN ?
TypeError: models.reducer is not a function
use .reduce instead of .reducer maybe result.reduce((coundData,sofa,index)=>{
|

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.