Search code examples
javascriptreactjsstatesemantic-ui

How to check and return value of state object array and use that to identify which object to take data from


The Aim: Use the value of i.id from the mapped components when clicked on to search state ids and locate the object which contains the same id value... When this object is found to return/update id and active values.

Clicking on the dynamic rendered component triggering onClick to change value of the current active: true to active: false and find object with id of the clicked component and this.setState({active:value}) in that object. Then if (active === true) render iframe containing the object's id value.

The state

this.state = {
      ids: [
        {
          id: "iCBvfW08jlo",
          active: true,
        },
        {
          id: "qvOcCQXZVg0",
          active: false,
        },
        {
          id: "YXNC3GKmjgk",
          active: false,
        },
      ],
    };

The components rendered for each state

{this.state.ids.map((i) => (
                    <Image
                      className="carouselitem"
                      rounded
                      fluid
                      src={
                        "http://img.youtube.com/vi/" + i.id + "/hqdefault.jpg"
                      }
                      size="small"
                    />
                  ))}

I am Really Stumped for what to do

I tried an if loop inside a for ...in... loop... but gave me nothing but errors when trying to render the page.

Full Code

import React from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import { Button, Embed, Icon, Image, List } from "semantic-ui-react";
import "./Services.css";
import logo from "./images/EIB 3D Logo v25.png";
import "react-responsive-carousel/lib/styles/carousel.min.css"; // requires a loader
import ReactPlayer from "react-player";
import MediaQuery from "react-responsive";

export default class Services extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      ids: [
        {
          id: "iCBvfW08jlo",
          active: true,
        },
        {
          id: "qvOcCQXZVg0",
          active: false,
        },
        {
          id: "YXNC3GKmjgk",
          active: false,
        },
      ],
    };
  }
  handleClick = (props) => {};
  render() {
    return (
      <div className="serviceswrap">
        <div className="servicesbdrop">
          <div className="primarywrap">
            <div className="primaryvideo">
              <div className="carousel">
                <div className="slider">
                  {this.state.ids.map((i) => (
                    <Image
                      className="carouselitem"
                      rounded
                      fluid
                      src={
                        "http://img.youtube.com/vi/" + i.id + "/hqdefault.jpg"
                      }
                      size="small"
                    />
                  ))}
                </div>
              </div>
            </div>
            <List size="big" className="servicesList">
              <List.Item>
                <List.Icon size="big" name="cog" />
                <List.Content>
                  <List.Header as="a">3D Printing</List.Header>
                  <List.Description>
                    Print your design using our 3d-printer.
                  </List.Description>
                </List.Content>
              </List.Item>
              <List.Item>
                <List.Icon size="big" name="cog" />
                <List.Content>
                  <List.Header as="a">CNC Machining</List.Header>
                  <List.Description>
                    Print your design using our CNC machienery.
                  </List.Description>
                </List.Content>
              </List.Item>
              <List.Item>
                <List.Icon size="big" name="cog" />
                <List.Content>
                  <List.Header as="a">Personalised Designs</List.Header>
                  <List.Description>
                    Design your idea to suite your needs.
                  </List.Description>
                </List.Content>
              </List.Item>
              <List.Item>
                <List.Icon size="big" name="cog" />
                <List.Content>
                  <List.Header as="a">Laser Etching</List.Header>
                  <List.Description>
                    Elegant designs etched onto wood.
                  </List.Description>
                </List.Content>
              </List.Item>
              <List.Item>
                <List.Icon size="big" name="cog" />
                <List.Content>
                  <List.Header as="a">Wood Working</List.Header>
                  <List.Description>
                    Build custom designed indoor and outdoor wooden signage.
                  </List.Description>
                </List.Content>
              </List.Item>
            </List>
          </div>
        </div>
      </div>
    );
  }
}


Solution

  • Well, it's actually very simple...

    onClick={() => {
                      this.setState((prevState) => ({
                        ids: prevState.ids.map((ob) =>
                          ob.id !== i.id
                            ? { ...ob, active: false }
                            : { ...ob, active: true }
                        ),
                      }));
                    }}
    

    this anon function finds the objects that have id!== i.id and updates their objects to active: false then updates the object with id === i.id

    Then this (the next codeblock) finds the object that has active: true and returns its id: value

    firstActiveId = () => {
        for (var i = 0; i < this.state.ids.length; i++) {
          if (this.state.ids[i].active) {
            return this.state.ids[i].id;
          }
        }
      };
    

    It is then passed into the element activevid where it completes the URL of the placeholder and the id of the iframe which is used to retrieve the youtube url.

     <div className="activevid">
              <Embed
                active
                autoplay={true}
                color="white"
                hd={false}
                id={this.firstActiveId(this.state.ids)}
                iframe={{
                  allowFullScreen: true,
                  style: {
                    padding: 0,
                  },
                }}
                placeholder={
                  "http://img.youtube.com/vi/" +
                  this.firstActiveId(this.state.ids) +
                  "/hqdefault.jpg"
                }
                source="youtube"
              />
            </div>
    

    Here is the full component to see the placements.

    import React, { Component } from "react";
    import { Embed, Image } from "semantic-ui-react";
    import "./Player.css";
    
    export default class Player extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          ids: [
            {
              id: "iCBvfW08jlo",
              active: false,
            },
            {
              id: "qvOcCQXZVg0",
              active: true,
            },
            {
              id: "YXNC3GKmjgk",
              active: false,
            },
          ],
        };
      }
      firstActiveId = () => {
        for (var i = 0; i < this.state.ids.length; i++) {
          if (this.state.ids[i].active) {
            return this.state.ids[i].id;
          }
        }
      };
    
     
    
      render() {
        return (
          <div className="carouselwrap">
            <div className="activevid">
              <Embed
                active
                autoplay={true}
                color="white"
                hd={false}
                id={this.firstActiveId(this.state.ids)}
                iframe={{
                  allowFullScreen: true,
                  style: {
                    padding: 0,
                  },
                }}
                placeholder={
                  "http://img.youtube.com/vi/" +
                  this.firstActiveId(this.state.ids) +
                  "/hqdefault.jpg"
                }
                source="youtube"
              />
            </div>
            <div className="thumbs">
              {this.state.ids.map((i) => (
                <>
                  <Image
                    className="carouselitem"
                    rounded
                    onClick={() => {
                      this.setState((prevState) => ({
                        ids: prevState.ids.map((ob) =>
                          ob.id !== i.id
                            ? { ...ob, active: false }
                            : { ...ob, active: true }
                        ),
                      }));
                    }}
                    src={"http://img.youtube.com/vi/" + i.id + "/hqdefault.jpg"}
                    size="small"
                  />
                </>
              ))}
            </div>
          </div>
        );
      }
    }