Perdixo
Perdixo

Reputation: 1299

Compare 2 array key and values in the same object

I am currently working on an app using Firebase (Realtime Database) and ReactJS. I have the following :

screenshot

I'd like to check in sellersList for values that are true. For each value that is true, i'd like to check into the sellers array for items containing the same value as the key from the first array in the "name : XXX" key-value pair.

Exemple : if i have "Nike" and "Puma" as true, i'd like to check in the sellers array for the items that have "Nike" and "Puma" as a name value, and return the whole parent objects (so i have access to the avatar, the link etc.).

Edit : here is my full component code :

import React, { Component } from 'react';
import Popup from '../Navbar/Popup';
import Upvote from './Upvote';
import actions from '../../actions';
import connectToStores from 'alt-utils/lib/connectToStores';
import ProductStore from '../../stores/ProductStore';

@connectToStores
class ProductPopup extends Component {
  constructor(props) {
    super(props);
    this.state = {
      sellers: [],
    };

    this.commentInput = React.createRef();
    this.handleCommentButton = this.handleCommentButton.bind(this);
  }

  static getStores() {
    return [ProductStore];
  }

  static getPropsFromStores() {
    return ProductStore.getState();
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (nextProps.status && this.props.status != nextProps.status) {
      actions.getComments(this.props.pid);
    }
    return true;
  }

  renderHeader() {
    return (
      <header>
        <section className="product-header-content">
          <div className="product-header-thumb">
            <img src={this.props.thumbnail} />
          </div>
          <div className="product-header-info">
            <h1>{this.props.name}</h1>
            <p>{this.props.tagline}</p>
          </div>
        </section>
      </header>
    );
  }

  renderContent() {
    return (
      <section className="product-container">
        <div className="product-main">
          <section className="product-infos_wrapper">
            <section>
              <img src={this.props.media} className="product-image" />
            </section>
            <section className="product-infos">
              <p>{this.props.description}</p>
            </section>
          </section>
        </div>

        <div className="product-aside">
          <div className="aside-btn">
            <Upvote {...this.props} />
          </div>
          <div className="product-links-list">
            <h3>Ou trouver la paire</h3>

            <ul className="product-sellers">
              {Object.keys(this.state.sellers)}
            </ul>
          </div>
        </div>
      </section>
    );
  }

  handleComment = (e) => {
    if (e.keyCode === 13 && e.target.value.length > 0) {
      var comment = {
        content: e.target.value,
        name: this.props.user.name,
        avatar: this.props.user.avatar,
      };

      actions.addComment(this.props.pid, comment);
      e.target.value = null;
    }
  };

  handleCommentButton() {
    if (this.commentInput.current.value.length > 0) {
      var comment = {
        content: this.commentInput.current.value,
        name: this.props.user.name,
        avatar: this.props.user.avatar,
      };
    }

    actions.addComment(this.props.pid, comment);
    this.commentInput.current.value = null;
  }

  renderBodyDiscussion() {
    return (
      <section className="discussion">
        <h2>Commentaires</h2>
        {this.props.user ? (
          <section className="post-comment">
            <img src={this.props.user.avatar} className="medium-avatar" />
            <input
              placeholder="Que pensez-vous de ce produit ?"
              onKeyUp={this.handleComment}
              ref={this.commentInput}
            />
            <button type="submit" className="btn btn-primary" onClick={this.handleCommentButton}>
              Envoyer
            </button>
          </section>
        ) : null}
        {this.renderComments()}
      </section>
    );
  }

  renderBody() {
    return (
      <section className="product-popup-body">
        <main>{this.renderBodyDiscussion()}</main>
      </section>
    );
  }

  renderComments() {
    return (
      <ul className="comment-list">
        {this.props.comments.map(function (comment, index) {
          return (
            <li key={index} className="comment-item">
              <div className="comment-item_user">
                <img src={comment.avatar} className="medium-avatar" />
                <strong>{comment.name}</strong>
              </div>

              <section className="comment-item_content">
                <p>{comment.content}</p>
              </section>
            </li>
          );
        })}
      </ul>
    );
  }

  render() {

    const allSellers = Object.keys(this.props.sellersList).reduce((o, key) => {
      this.props.sellersList[key] !== false && (o[key] = this.props.sellersList[key]);

      this.state.sellers = o;
      return o;
    }, {});

    console.log(this.props);

    return (
      <Popup {...this.props} style="product-popup">
        {this.renderHeader()}
        {this.renderContent()}
        {this.renderBody()}
      </Popup>
    );
  }
}

export default ProductPopup;

Upvotes: 1

Views: 831

Answers (2)

Anthony
Anthony

Reputation: 6502

I think this might be what you're looking to do:

const sellers = [
  { avatar: "1", name: "Nike" },
  { avatar: "2", name: "Puma" },
  { avatar: "3", name: "Something" },
];

const sellersList = {
  Nike: true,
  Puma: true,
  Something: false,
};

const includedSellers = Object.keys(sellersList).filter(
  (brand) => sellersList[brand]
);

const results = sellers.reduce(
  (results, seller) =>
    includedSellers.includes(seller.name) ? [seller, ...results] : results,
  []
);

console.log(results);

//BETTER SOLUTION FROM @Drew Reese
const results2 = sellers.filter(({ name }) => includedSellers.includes(name));

console.log(results2);

This will give you an array of objects from the sellers array, where seller.name is a property from sellersList with a truthy value.

EDIT: As @Drew Reese pointed out, you can achieve this with just filter:

const results = sellers.filter(seller => includedSellers.includes(seller.name));

Upvotes: 3

Gerardo Perrucci
Gerardo Perrucci

Reputation: 734

you have to avoid mutate the state manually like this:

  this.state.sellers = o; //

https://reactjs.org/docs/state-and-lifecycle.html#using-state-correctly

Upvotes: -1

Related Questions