React axios api call with user input

I’m very new to react and I am trying to make an api call based on user-input using axios. I’m able to get the results with the hard-coded query(‘cars’) on form submit, but I’d like to be able to allow the user to search different items. I’m stuck on how to connect the user input to the api call.

import axios from "axios";

import { useState, useEffect } from "react";

function App() {
  const [data, setData] = useState([]);
  const [userInput, setUserInput] = useState([]);

  const handleSubmit = (event) => {
    event.preventDefault();
    axios({
      url: "https://api.unsplash.com/search/photos",
      method: "GET",
      dataResponse: "json",
      params: {
        client_id: "d54vE8fu6bjJ_JgkBqugaZOt4bwFHGkmiKDGHunnXxc",
        query: "cars",
        per_page: 10,
      },
    }).then((response) => {
      console.log(response.data.results);
      setData(response.data.results);
    });
  };

  return (
    <div>
      <form action="" onSubmit={handleSubmit}>
        <label htmlFor="search">Search</label>
        <input
          id="search"
          type="text"
          value={userInput}
          onChange={(event) => setUserInput(event.target.value)}
        />
      </form>

      <div>
        {data.map((item) => {
          return (
            <div key={item.id}>
              <img src={item.urls.thumb} alt="" />
            </div>
          );
        })}
      </div>
    </div>
  );
}

export default App;

How can I push objects to arrays with similar names?

I have a form that I can create duplicate sections. Right now when the form is submitted the form spits out one giant object. I’m working on a filter function that can filter out the duplicate sections and organize the duplicates in array so it works with my API.

e.g.

// base object

  {
    question_10: ""
    question_10a: ""
    question_11_checkbox: false
    question_11_checkbox_copy_0: false
    question_11_checkbox_copy_1: true
    question_11_text: "110 Monroe St"
    question_11_text_copy_0: "186 Aspen Road"
    question_12_checkbox: false
    question_12_checkbox_copy_0: false
    question_12_text: "New York"
    question_12_text_copy_0: "South Orange"
    ...
  }

// what I want is

{
  question_10: ""
  question_10a: ""
  question_11_checkbox: false
  question_11_checkbox_copies: [
    { question_11_checkbox_copy_0: false } 
    { question_11_checkbox_copy_1: true }
  ]
  question_11_text: "101 Monroe St"
  question_11_text_copies: [
    { question_11_text_copy_0: "186 Aspen Road"}
  ]
  question_12_checkbox: false
  question_12_checkbox_copies: [
    { question_12_checkbox_copy_0: false}
  ]
  question_12_text: "New York"
  question_12_text_copies: [
    { question_12_text_copy_0: "South Orange"}
  ]

   ...
 }

So far I’ve been able to filter out the copies from the original object and create the arrays for the copies

 // filter out copy keys
const copiesKey = Object.keys(data).filter(key => key.includes('copy'));

const copy = {};

// create arrays for copies
copiesKey.map(copiedQuestion => {

  if (!(`${copiedQuestion.slice(0, copiedQuestion.length - 7)}_copies` in copy)) {
    copy[`${copiedQuestion.slice(0, copiedQuestion.length - 7)}_copies`] = [];
  }
});

Where I’m stuck is it’s not clear how to match the object to the appropriate array and push it.
e.g.

question_11_text_copies: [
  { question_11_text_copy_0: "186 Aspen Road" }
]

So far I’ve tried to slice the last three keys of the copy_0 object and match the key to the array name by using array.filter, but that didn’t work as expected.

How can I match the ‘copy_n’ objects to the appropriate array and push those objects to the array?

Angular Material removes previous styling after installation

I made a Homepage for my company and i wanted to add a contact form with angular material. After i installed Angular Material all my h1 and h2 an p stylings are like removed or overwritten.
When i remove the Angular Material code in the global styles.scss file the headlines and texts are back to normal but the material components are not styled.

Here are some screenshots:

This is without the material code in the styles.scss – this is how it should look
This is without the material code in the styles.scss - this is how it should look

And this is how it looks with the code
And this is how it looks with the code

and here is the code thats added to styles.scss:

// Custom Theming for Angular Material
// For more information: https://material.angular.io/guide/theming
@use '@angular/material' as mat;
// Plus imports for other components in your app.

// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Be sure that you only ever include this mixin once!
@include mat.core();

// Define the palettes for your theme using the Material Design palettes available in palette.scss
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
// hue. Available color palettes: https://material.io/design/color/
$website-primary: mat.define-palette(mat.$indigo-palette);
$website-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);

// The warn palette is optional (defaults to red).
$website-warn: mat.define-palette(mat.$red-palette);

// Create the theme object. A theme consists of configurations for individual
// theming systems such as "color" or "typography".
$website-theme: mat.define-light-theme((
  color: (
    primary: $website-primary,
    accent: $website-accent,
    warn: $website-warn,
  )
));

// Include theme styles for core and each component used in your app.
// Alternatively, you can import and @include the theme mixins for each component
// that you are using.
@include mat.all-component-themes($website-theme);

Data on the middle when is one series

I have this area chart, and this has just one data set. My question is, how can I show that data on the middle where is the label and not besides the Y axis. I used the tickPlacement: ‘between’ on the xaxis option but doesn’t work. Any thoughts?

enter image description here

Thanks!

How do I pass a variable and the function to update it’s state as a prop in React?

if I have variable as such:

const [APIKey, setAPIKey] = useState([])

Can I group these into 1 variable and pass it along as a prop?

const passAPI = {APIKey, setAPIKey}

Here is how I’m attempting to pass it:

const Home = () => {

  const [APIKey, setAPIKey] = useState([])
  const [Symbols, setSymbols] = useState([])
  const [Endpoint, setEndpoint] = useState([])
  const [Base, setBase] = useState([])

  const passAPI = {APIKey, setAPIKey}
  const passSymbols = {Symbols, setSymbols}
  const passEndpoint = {Endpoint, setEndpoint}
  const passBase = {Base, setBase}

  return (
  <Grid container spacing='8' className='HomeWrapper'>
    <Grid item sx={{ display: { xs: 'none', sm: 'flex' }, width: '50%' }} className='x1'>
      <Paper elevation='6' className='HomePaper' sx={{ width: '100%'}}>
        <TopLeft passAPI={passAPI} passSymbols={passSymbols} passEndpoint={passEndpoint} passBase={passBase}/>
      </Paper>
    </Grid>
...

And here is an example of how I was trying to use it:

const TopRight = ({passAPI, passSymbols, passEndpoint, passCurrency}) => {

  return (
    <Box className='TopRightWrapper' sx={{ display: 'flex', flexDirection: 'column' }} pl={2} pt={1} pb={1}>
      <FormControl onSubmit={passAPI}>
        <Box>
          <InputLabel htmlFor="my-input">API Key</InputLabel>
          <Input id="my-input" aria-describedby="my-helper-text" />
          <button type='submit'>click</button>
        </Box>
      </FormControl>

I would want to use the setAPIKey function that is found in the passAPI variable. How do I go about this?

How to get all query params using React-Router-DOM v6 `useSearchParams` without specifying the key?

I’m currently working on a React project with react-router-dom v6 and I want to get all of the query parameters.

http://localhost:3000/users?page=5&pageSize=25

I want to get both page and pageSize. I know that we can use this code below to get params with the keys.

import React from 'react'
import {useSearchParams} from "react-router-dom";

const Users = () => {

  const [searchParams, setSearchParams] = useSearchParams();

  const page = searchParams.get('page')
  const pageSize = searchParams.get('pageSize')


  return (<h1>page: {page}, pageSize: {pageSize}</h1>)
}

But, then I tried to get all params without specifying the keys by using searchparams.getAll() but it didn’t work and the React app showed only a blank page.

Here is my code I used to get all params:

import React from 'react'
import {useSearchParams} from "react-router-dom";

const Users = () => {

  const [searchParams, setSearchParams] = useSearchParams();

  const params = searchParams.getAll();

  console.log(params)

  return (<h1>params</h1>)
}

Did I make any mistake there?

This is my dependencies on package.json:

  "dependencies": {
    ...,
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "^6.2.2",
    ...,
  },

How to select multiple elements using js

How can I select all elements that has the same class name? I’m having trouble using the method .getElementsByClassName().

This is my js code.

let pop_up = document.querySelector('#overlay')
let button = document.getElementsByClassName('button')
let close_popUp = document.getElementById('close__pop_up')

function open_popUp() {
    pop_up.style.display = 'block'
}

button.addEventListener('click', open_popUp)  

close_popUp.addEventListener('click', function(){
    pop_up.style.display = 'none'
})

And this is my html:

<section class="membership__options">
          <div class="membership__options__card">
            <img src="./assets/img/drinks-1.jpg" alt="Drinks" />
            <p class="membership__price">10% OFF</p>
            <p class="membership__description">Bar</p>
            <button class="button membership__button" type="button" value="Submit">sign up</button>
          </div>
          <div class="membership__options__card">
            <img src="./assets/img/live-music.jpg" alt="Singer singing" />
            <p class="membership__price">15% OFF</p>
            <p class="membership__description">Live Music</p>
            <button class="button membership__button" type="button" value="Submit">sign up</button>
          </div>
          <div class="membership__options__card">
            <img src="./assets/img/drinks.jpg" alt="A guy drinking" />
            <p class="membership__price">20% OFF</p>
            <p class="membership__description">Bar + Music</p>
            <button class="button membership__button" type="button" value="Submit">sign up</button>
          </div>
        </section>

Problem reading document.getElementById().value

I’m newer to Javascript and the proper handling of event listeners; it would greatly appreciated if you could offer any help. My program is an e-commerce project, and i’m currently trying to receive 2 event listeners ( sizeChosen , qty ) which describe the size of the product selected and the quantity or amount of products.

Some Technologies used: MongoDb , Express React , Redux , Node.js , axios

I had encountered this issue when trying to implement the Size event listener selector option, previously when i had only recorded quantity it worked fine. So far I’ve been able to read around and I’ve been able to get the input printed in the DOM via console.log , but whenever I alter
const sizeChosen = document.getElementById(‘sizeChosen’);
[![const sizeChosen = document.getElementById(‘sizeChosen’);][1]][1]

to
const sizeChosen = document.getElementById(‘sizeChosen’).value;
it then causes a flood of these errors that lose me.

[![after using getElementById().value][2]][2]

How can i clean up these errors and safely use the user’s selected size in the next cart.js screen? Upon examing Redux Devtools, the json object shows that the sizeChosen for some reason isn’t receiving the selected size on singleProduct.js.
[![enter image description here][3]][3]

** singleProduct.js -> shows a product from the mongoDB for the client to purchase and select size & quantity wanted with a [add to cart] button that sends user to cart.js **
[![enter image description here][4]][4]

import React, { useEffect, useState } from "react";
import Header from "./../components/Header";
import Rating from "../components/homeComponents/Rating";
import { Link } from "react-router-dom";
import Message from "./../components/LoadingError/Error";
import { useDispatch, useSelector } from "react-redux";
import {
  createProductReview,
  listProductDetails,
} from "../Redux/Actions/ProductActions";
import Loading from "../components/LoadingError/Loading";
import { PRODUCT_CREATE_REVIEW_RESET } from "../Redux/Constants/ProductConstants";
import moment from "moment";
import ImageGalleryComponent from '../components/homeComponents/image-gallery.component';

const SingleProduct = ({ history, match }) => {
  const [qty, setQty] = useState(1);
  const [sizeChosen, setSizeChosen] = useState(1);
  const [rating, setRating] = useState(0);
  const [comment, setComment] = useState("");

  const productId = match.params.id;
  const dispatch = useDispatch();
  const productDetails = useSelector((state) => state.productDetails);
  const { loading, error, product } = productDetails;
  const userLogin = useSelector((state) => state.userLogin);
  const { userInfo } = userLogin;
  const productReviewCreate = useSelector((state) => state.productReviewCreate);
  const {
    loading: loadingCreateReview,
    error: errorCreateReview,
    success: successCreateReview,
  } = productReviewCreate;

  useEffect(() => {
    if (successCreateReview) {
      alert("Review Submitted");
      setRating(0);
      setComment("");
      dispatch({ type: PRODUCT_CREATE_REVIEW_RESET });
    }
    dispatch(listProductDetails(productId));
  }, [dispatch, productId, successCreateReview]);

  const AddToCartHandle = (e) => {
      e.preventDefault();
      history.push(`/cart/${productId}?qty=${qty}`);
  };....

** cart.js -> shows all cart items and sizes chosen **
[![enter image description here][5]][5]

import React, { useEffect } from "react";
import Header from "./../components/Header";
import { Link } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import { addToCart, removefromcart } from "./../Redux/Actions/cartActions";

const CartScreen = ({ match, location, history }) => {
    window.scrollTo(0, 0);
    const dispatch = useDispatch();
    const productId = match.params.id;
    const qty = location.search ? Number(location.search.split("=")[1]) : 1;
    const sizeChosen = document.getElementById('sizeChosen');
    const cart = useSelector((state) => state.cart);
    const { cartItems } = cart;
    console.log(sizeChosen);
  const total = cartItems.reduce((a, i) => a + i.qty * i.price, 0).toFixed(2);

  useEffect(() => {
    if (productId) {
      dispatch(addToCart(productId, qty));
      }
  }, [dispatch, productId, qty]);

  const checkOutHandler = () => {
    history.push("/login?redirect=shipping");
  };

  const removeFromCartHandle = (id) => {
    dispatch(removefromcart(id));
  };
  const productDetails = useSelector((state) => state.productDetails);
  const { loading, error, product } = productDetails;....

full sections of code can be provided if requested via github.Thanks for reading this far, your a champion and true scholar!
[1]: https://i.stack.imgur.com/ESkgC.png
[2]: https://i.stack.imgur.com/84n6C.png
[3]: https://i.stack.imgur.com/go7Af.png
[4]: https://i.stack.imgur.com/qHvcp.png
[5]: https://i.stack.imgur.com/O9fg2.png

I need to replace the div that contains youtube video with the previous state when the user scrolls beyond that div while playing video

thank you so much for taking time to look in to this issue .

I have a page where it contains multiple videos from youtube , i want to replace that video content with the image whenever the user scrolls down beyond that div , it is working fine for one video but when there is multiple videos it is taking the image of last video for all the videos .

Here is my initial html :

<p>this is first paragraph</p>
 <div class="main-paragraph">
   <div class="video-content">
     <img src="/sites/default/files/image1.jpg" alt="">
     <button class="video-play"></button>
   </div>
 </div>
 <p>this is second paragraph</p>
 <div class="main-content">
   <div class="video-content">
     <img src="/sites/default/files/image2.jpg" alt="">
     <button class="video-play"></button>
   </div>
 </div>
   

Let’s say for example if user plays the video 1 the html becomes like this :

<p>this is first paragraph</p>
<div class="main-paragraph">
  <div class="video-content">
    <iframe width="854" height="480" frameborder="0" allowfullscreen="allowfullscreen" title="Video Player" class="video-player" src="https://www.youtube.com/embed/s6OusrTxwxA?autoplay=1&amp;start=0&amp;rel=0&amp;enablejsapi=1" data-gtm-yt-inspected-1927822_387="true" id="427043625">
  </div>
</div>
<p>this is second paragraph</p>
<div class="main-content">
  <div class="video-content">
    <iframe width="854" height="480" frameborder="0" allowfullscreen="allowfullscreen" title="Video Player" class="video-player" src="https://www.youtube.com/embed/DKpkL3ZyLBo?autoplay=1&amp;start=0&amp;rel=0&amp;enablejsapi=1" data-gtm-yt-inspected-1927822_387="true" id="427043625">
  </div>
</div>  

So if users scroll’s down while playing the video , i want replace that video with the image for that specific div similar to like this :

<p>this is first paragraph</p>
    <div class="main-paragraph">
      <div class="video-content">
   <img src="/sites/default/files/image1.jpg" alt="">
        <button class="video-play"></button>
      </div>
    </div>
    <p>this is second paragraph</p>
    <div class="main-content">
      <div class="video-content">
        <iframe width="854" height="480" frameborder="0" allowfullscreen="allowfullscreen" title="Video Player" class="video-player" src="https://www.youtube.com/embed/DKpkL3ZyLBo?autoplay=1&amp;start=0&amp;rel=0&amp;enablejsapi=1" data-gtm-yt-inspected-1927822_387="true" id="427043625">
      </div>
    </div>

Here is my jquery :

$(document).ready(function() {
            $('.main-paragraph').each(function() {
                let old_html = $(this).find('.video-content').html();
                // Stop playing the video and show image when scrolled past.
                $(window).scroll(function() {
                    $('.video-content').each(function() {
                        let windowScroll = $(window).scrollTop(); // how many pixels you've scrolled
                        let containerDistance = $(this).offset().top;
                        let containerHeight = $(this).height(); // height of container in pixel
                        // If you've scrolled further than the top of the container + it's height
                        // stop the video.
                        if (windowScroll > containerDistance + containerHeight) {
                            $(this).html(old_html);
                        }
                    });
                });
            });

TypeError karma test : subscribe is not a function

I have a karma unit test and the test fails with below error.

this.gridApi.getScaleWidth().subscribe is not a function

GridApi.ts

export class GridApi {

    private scaleWidthSubject = new BehaviorSubject<{value: number}>({value: 0});

    public getScaleWidth(): Observable<{value:number}> {
        return this.scaleWidthSubject;
    }
}

GridComponent.ts

export class GridComponent implements OnInit, OnDestroy, AfterViewInit {

    private subscribeToValueChanges() {        
        this.scaleWidth$ = this.gridApi.getScaleWidth().subscribe( width => {
        this.scaleWidth = width.value;
    });

 }
}

Component.spec.ts

describe('GridComponent', () => {

beforeEach(async () => {
    const mockGridApiService = jasmine.createSpyObj("GridApi", {
        getScaleWidth () : Observable<{value: number}> {
            let scaleWidthSubject = new BehaviorSubject<{value: number}>({value: 0});
            return scaleWidthSubject.asObservable();
        }
    });
}

await TestBed.configureTestingModule({
    providers: [ { provide: GridApi, useValue: mockGridApiService} ],
    imports: [
        HttpClientModule
    ],
    declarations: [ GridComponent ]

})
}

What should the mock getScaleWidth() return to pass the test. Not sure what I’m missing here.

My javascript “click” function only works once

i’m beginner with JS/html/css and face a problem now.

I’m trying to give some style to my cursor thanks javascript, with a mark that follows the cursor everywhere on screen. Now i’m trying to apply a specific style when I click on the page. The problem is that my function works but only once. Then I have to refresh the page so it can work again. I’ve used an addEventListener method with ‘click’, that I think is the proper method. I show you my code :

var cursor1 = document.querySelector(".cursor1");
var cursor2 = document.querySelector(".cursor2");
/*

this was some test.

function testscale(){
    cursor1.animate(
        [{transform: 'scale(1)'},{transform: 'scale(0)'}],
        {duration:200}
        );
*/


document.addEventListener('click', function(){
    cursor1.classList.add("cursoranimation");
});
--//


document.addEventListener('mousemove', function(e){
    cursor1.style.cssText = cursor2.style.cssText = "left: " + e.clientX + "px; top: " + e.clientY + "px;";
});

Do you have some advice for my situation ? Thank you ! (i’m not using jquery)

How to change the styling of an element using JS when it has no class or ID?

I have a html file (converted from docx) and it does not have any class names or ids. How can I style it using JS? For example, if I need to change the color of the heading for the below file HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="./script.js"></script>
    <title>Document</title>
  </head>
  <body>
    <h1>This is the heading</h1>
    <p>Hello, my name is xyz and this is a para</p>
  </body>
</html>

This is what I tried, but document.getElementByTagName() does not return the element like document.getElementById()

console.log('hello world');
Heading = document.getElementsByTagName('h1');
console.log(Heading);
Heading.style.color = 'blue';

Edit:
I tried the below code, but it returns undefined

console.log('hello world');
Heading = document.getElementsByTagName('h1')[0];
console.log(Heading);
Heading.style.color = 'blue';

enter image description here

js reduce method point of array

In the reduce method the following works:

let dolphins = [92,108,89]
dolphins = dolphins.reduce(function(a,b){
   return a + b/dolphins.length},0)

note that inside the reduce function we have access to dolphins.

From the documentation we have:

array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

Parameters

Parameter   Description
function()  Required.
A function to be run for each element in the array.
Reducer function parameters:
total           Required.
                The initialValue, or the previously returned value of the function.
currentValue    Required.
                The value of the current element.
currentIndex    Optional.
                The index of the current element.
arr             Optional.
                The array the current element belongs to.

What’s the point of passing the array since the function already has access to it?