Props,State and CombineReducer in React JS

Given is an AuthenticationReducer:

import * as authenticationActions from "./AuthenticationAction";
//import * as managementActions from "./ManagementAction";

const initialState = {
  user: null,
  loginPending: false,
  showLoginDialog: false,
  showCreateUserDialog: false,
  showUpdateUserDialog: false
};
function authenticationReducer(state = {}, action) {
  console.log("Bin im Reducer" + action.type);

  switch (action.type) {
    case authenticationActions.SHOW_LOGIN_DIALOG:
      return {
        ...state,
        showLoginDialog: true,
        error: null,
      };

    case authenticationActions.HIDE_LOGIN_DIALOG:
      return {
        ...state,
        showLoginDialog: false,
        error: null,
      };
default:
  return state;
}
}

export default authenticationReducer;

The reducer works independently, but if I use combineReducer I cannot use the login-Dialog in UserSessionWidget any longer.

index.js

import thunk from 'redux-thunk'
import App from './App';
import reportWebVitals from './reportWebVitals';
import authenticationReducer from './redux/authentication/AuthenticationReducer'
import { combineReducers } from 'redux';

const initialState = {}
const middleware=[thunk]
const reducer = combineReducers({
  authenticationReducer: authenticationReducer
  
})
const store = createStore(reducer,initialState,applyMiddleware(...middleware))

UserSessionWidget

import React, { Component } from "react";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import Button from "react-bootstrap/Button";
import Modal from "react-bootstrap/Modal";
import Form from "react-bootstrap/Form";
import * as authenticationActions from "../actions/AuthenticationAction";

const mapStateToProps = (state) => {
  return state;
};

class UserSessionWidget extends Component {
  constructor(props) {
    super(props);
    this.state = { userID: "", password: "" };
    this.handleShow = this.handleShow.bind(this);
    this.handleClose = this.handleClose.bind(this);
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleShow(e) {
    e.preventDefault();
    /* this.setState({show: true}) */
    const { showLoginDialogAction } = this.props;
    showLoginDialogAction();
  }
  handleClose(e) {
    e.preventDefault();
    this.setState({ show: false });
    const { hideLoginDialogAction } = this.props;
    hideLoginDialogAction();
  }

  handleChange(e) {
    const { name, value } = e.target;
    this.setState({ [name]: value });

    console.log(JSON.stringify(this.state));
  }

  handleSubmit(e) {
    e.preventDefault();
    const { userID, password } = this.state;
    const { authenticateUserAction } = this.props;
    authenticateUserAction(userID, password);
    console.log("Pushed submit");
  }

  render() {
    var showDialog = this.props.showLoginDialog;
    if (showDialog == undefined) {
      showDialog = false;
    }

    return (
      <div>
        <Button variant="primary" onClick={this.handleShow}>
          Login
        </Button>
        <Modal show={showDialog} onHide={this.handleClose}>
          <Modal.Body>
            <Form>
              <Form.Label>userID</Form.Label>
              <Form.Control
                id="LoginUserIDInput"
                type="text"
                placeholder="User ID"
                name="userID"
                onChange={this.handleChange}
              />
              <br />

              <Form.Label>password</Form.Label>
              <Form.Control
                id="LoginPasswordInput"
                type="password"
                placeholder="Password"
                name="password"
                onChange={this.handleChange}
              />

              <Button
                variant="primary"
                type="submit"
                onClick={this.handleSubmit}
              >
                Submit
              </Button>
            </Form>
          </Modal.Body>
          <Modal.Footer>
            <Button variant="primary" onClick={this.handleClose}>
              Close
            </Button>
          </Modal.Footer>
        </Modal>
      </div>
    );
  }
}

const mapDisaptchToProps = (dispatch) =>
  bindActionCreators(
    {
      showLoginDialogAction: authenticationActions.getShowLoginDialogAction,
      hideLoginDialogAction: authenticationActions.getHideLoginDialogAction,
      authenticateUserAction: authenticationActions.authenticateUser,
    },
    dispatch
  );
const ConnectedUserSessionsWidget = connect(
  mapStateToProps,
  mapDisaptchToProps
)(UserSessionWidget);

export default ConnectedUserSessionsWidget;

My App.js starts like this:

const mapStateToProps =state => {
  return state
}

question: It can be conjectured that the state in mapsStateToProps is not transferred. How should I change the mapStateToProps to use UserSessionWidget properly ? Or is the error anywhere else ?

How to Reload to same Page while sending a parameter?

I need to reload the page whenever different buttons are pressed, while sending a String to the same page so that on created() it takes that String and sends an HTTP Get into my Database.

Currently I have the following:

export default {
    data(){
        return{
            events: [],
            formData:{
                sportType: 'Ténis'
            }
        }
    },

    created(){
        //Do something here to get the value sent from the reloading
        axios.get(`http://localhost:8001/evento`, {headers: {sportType: this.formData.sportType}})
            .then((response)=>{
                this.events = response.events
            },(error) =>{
                console.log(error);
        });
    },
    pickSport(item){
                
    }

The function pickSport() is called whenever the buttons are pressed and each sends a value to this function that is a String. The idea now is to be able to reload the page when this function is called, while sending this item to the reloaded page, so I can update the value of sportType. I tried:

        pickDesporto(item){
            this.$router.push({
                path: '/betting',
                params: item
            });
        }

But with no success, since it keeps giving me a NavigationDuplicated error. How can I solve this?

How Do I change the color of webgl points?

This is the code I used to try to change the color of WebGL points:

I want to change the color of WebGL points when a user clicks the body element.
And FYI the shaders are compiling correctly.

The numbers in the color_obj object seem to be changing when I click on the screen. However, the WebGL colors don’t change. Can someone help me with this?

const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl");

gl.clearColor(0.3, 0.6, 0.7, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT || gl.DEPTH_BUFFER_BIT);

if (!gl) {
    throw new Error("WebGL not supported");
}

console.log("This is working");

const points = [
    1.0, 1.0, 0.0,
    1.0, -1.0, 0.0,
    -1.0, -1.0, 0.0,
    1.0, 1.0, 0.0,
    -1.0, -1.0, 0.0,
    -1.0, 1.0, 0.0
];

let color_obj = {
    color_1: 0.4,
    color_2: 0.7,
    color_3: 0.8,
    color_4: 0.0,
    color_5: 0.5,
}

let colors = [
    color_obj.color_1, color_obj.color_2, color_obj.color_3,
    color_obj.color_3, color_obj.color_1, color_obj.color_3,
    color_obj.color_4, color_obj.color_4, color_obj.color_4,
    color_obj.color_1, color_obj.color_2, color_obj.color_3,
    color_obj.color_4, color_obj.color_4, color_obj.color_4,
    color_obj.color_5, color_obj.color_5, color_obj.color_5
];

const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(points), gl.STATIC_DRAW);

const buffer_2 = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer_2);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW)

const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, `
precision mediump float;

attribute vec3 pos;
attribute vec3 rgb;
varying vec3 rgbColor;

void main() {
    rgbColor = rgb;
    gl_Position = vec4(pos, 1);
}
`);
gl.compileShader(vertexShader);

const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, `
precision mediump float;

varying vec3 rgbColor;

void main() {
    gl_FragColor = vec4(rgbColor, 1);
}
`);
gl.compileShader(fragmentShader);

const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);

const positionRef = gl.getAttribLocation(program, `pos`);
gl.enableVertexAttribArray(positionRef);
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.vertexAttribPointer(positionRef, 3, gl.FLOAT, false, 0, 0);

const colorRef = gl.getAttribLocation(program, `rgb`);
gl.enableVertexAttribArray(colorRef);
gl.bindBuffer(gl.ARRAY_BUFFER, buffer_2);
gl.vertexAttribPointer(colorRef, 3, gl.FLOAT, false, 0, 0);

gl.useProgram(program);

document.body.addEventListener("mouseup", () => {
    console.log("Body Clicked");
    color_obj.color_1 += 0.1;
    color_obj.color_2 += 0.1;
    color_obj.color_3 += 0.1;
    color_obj.color_4 += 0.1;
    color_obj.color_5 += 0.1;

    console.log(color_obj.color_1);
    console.log(color_obj.color_2);
    console.log(color_obj.color_3);
    console.log(color_obj.color_4);
    console.log(color_obj.color_5);
});

function animate() {
    requestAnimationFrame(animate);

    gl.drawArrays(gl.TRIANGLES, 0, 6);
}

requestAnimationFrame(animate);
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>WebGL</title>
    <style>
        canvas {
            position:fixed;
            width:100%;
            height:100%;
        }

        html, body {
            margin:0 !important;
            padding:0 !important;
            overflow:hidden;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
    <script src="app.js"></script>
</body>

</html>

How to pass the key used from JSON response objects in a map as a parameter for onclick() function in React?

I have tried to create a list of ‘League’ objects from the server, the user can click to create a league successfully, but to join a league the user will need to click the icon and the parameter will need to be sent to the joinLeague() function as the league.leagueId is required to join the league by the API:

LeagueList component:

 constructor(props) {
    super(props);
    this.state = {
        leagues: []
    };

    this.createLeague = this.createLeague.bind(this);

    this.joinLeague = this.joinLeague.bind(this);
}

 joinLeague() {
    const payload = {
        "username": localStorage.getItem("username"),
        "leagueId":
    };
    fetch(JOIN_LEAGUE_URL, {
        method: 'POST',
        headers: {
            "Accept": "application/json",
            "Content-Type": "application/json",
            "Authorization": localStorage.getItem("token")
        },
        body: JSON.stringify(payload)
    })
        .then(response => response.json())
        .then();
}

   render() {
        const {leagues} = this.state;

    const leagueList = leagues.map(league => {
        return <tr key={league.leagueId}>
            <td style={{whiteSpace: 'nowrap'}}>{league.leagueCreatorUsername}</td>
            <td>{league.playerCount}/10</td>
            <td>{league.matchesPerPlayer}</td>
            <td>{league.numberOfGamesPlayed}</td>
            <td>{league.totalGamesToBePlayed}</td>
            <i className="fas fa-plus" onClick={this.joinLeague}></i>
        </tr>
    });

}

In the joinLeague() function above you can see I am trying to create the payload but I need the leagueId from the as a parameter.

How can I accomplish this? I have tried {this.joinLeague.bind(league)} but it didn’t work, thanks.

React and Next postMessage communication CORS problem

I have two apps – CRA running on port 3000, and Next running on 3005.

In Next app I have simple message event listener:

  useEffect(() => {
    const handleMessage = (event: MessageEvent<{}>) =>
      console.log('Message event: ', event);

    window.addEventListener('message', handleMessage);
    return () => {
      window.removeEventListener('message', handleMessage);
    };
  }, []);

And I’ve set up headers in next.config.js:

const securityHeaders = [
  { key: 'Access-Control-Allow-Credentials', value: 'true' },
  { key: 'Access-Control-Allow-Origin', value: '*' },
  {
    key: 'Access-Control-Allow-Methods',
    value: 'GET,OPTIONS,PATCH,DELETE,POST,PUT',
  },
  {
    key: 'Access-Control-Allow-Headers',
    value:
      'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version',
  },
];

const nextConfig = {
  async headers() {
    return [
      {
        // Apply these headers to all routes in your application.
        source: '/:path*',
        headers: securityHeaders,
      },
    ];
  },
};

module.exports = nextConfig;

In React app I’m calling postMessage through iframe tag like this:

export const Frame = () => {
  const frameRef = useRef<HTMLIFrameElement>(null);

  const handleFrameLoad = () => {
    frameRef?.current?.contentWindow?.postMessage('TEST');
  };

  return (
    <iframe
      src="http://localhost:3005"
      ref={frameRef}
      onLoad={handleFrameLoad}
      sandbox="allow-same-origin allow-scripts"
    />
  );
};

And I’m still receiving error below in CRA’s console.

Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('http://localhost:3000') does not match the recipient window's origin ('http://localhost:3005').

Is there anything else that I can do to allow postMessage communication between two different local ports in NextJS?

await hitting timeout in jest unit test?

import { fs } from 'memfs';

describe('copyFolder()', () => {
  it('should work', async () => {
    await fs.promises.mkdir('/tmp/destination');
    console.log(fs.existsSync('/tmp/destination'));
  });
});

I’ve verified that fs.promises.mkdir('/tmp/destination') will return a promise and hence by having an await in front of it should be able to resolve it but seems like this is not the case for jest? it will just hit timeout instead?

Anyone has any clue about this?

Can you make a map based off address firebase?

I am trying to make a program that creates a google map based off the address given by user input. As i can not manually embed a link for each page, how can i make it so that when a user answers a form with the address I can take that address and make a google map. Do i have to convert the address to latitude and longitude and then do that?

Show wallet address after connecting Metamask with Web3.js

I got this code off github which allows you to connect to MetaMask using web3.js and also to make payment. I then modified it to

  1. Display a Connect Button when user is not logged in by checking if the content of an element is empty and if it is not empty, the connect button is hidden.
  2. Retrieve the connected wallet address which is in the element that hides the button.

I want the connected wallet to show up and hide the Connect button as soon as MetaMask is connected but it does not do that until i manually reload the page

Below is my code

  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
   <script src="https://unpkg.com/@metamask/legacy-web3@latest/dist/metamask.web3.min.js"></script>
  </head>
  <body>
    <div>
        
      <div id="selected-account"></div>
      <button class="pay-button">Pay</button>
      <div id="status"></div>
      <div id="accTabs"></div>
    </div>
    <script type="text/javascript">
      async function initWeb3() {
        if (window.ethereum) {
        window.web3 = new Web3(ethereum);
        
        try {
            
          await ethereum.enable();
    window.location.reload();
          } catch (err) {
            $("#status").html("User denied account access", err);
          }
        } else if (window.web3) {
            
          return (window.web3 = new Web3(web3.currentProvider));
          
        } else {
          return $("#status").html("No Metamask (or other Web3 Provider) installed");
        }
      }
      
      selectedAccount = ethereum.selectedAddress;
  document.querySelector("#selected-account").textContent = selectedAccount;

      $(".pay-button").click(async () => {
        await initWeb3();
        // paymentAddress is where funds will be send to
        const paymentAddress = "0x192c96bfee59158441f26101b2db1af3b07feb40";
        const amountEth = "1";



        web3.eth.sendTransaction(
          {
            to: paymentAddress, 
          value: web3.toWei(amountEth, 'ether')
          },
          (err, transactionId) => {
            if (err) {
              console.log("Payment failed", err);
              $("#status").html("Payment failed");
            } else {
              console.log("Payment successful", transactionId);
              $("#status").html("Payment successful");
            }
          }
        );
      });
    </script>
    
    <script>
  if ($('#selected-account').text() == '') {
document.getElementById("accTabs").innerHTML = '<button onclick="initWeb3()">Connect Ethereum</button>';
} else {


}
     
</script>
  </body>
</html> 

Your help will be appreciated!

Thanks for your assistance.

DOM update disabled after form submit in some browsers?

I have a simple <form action='/a/url' method='POST' onSubmit='setInterval(my_func, 1000)'.

The POST triggers a ~40 second operation, so my_func is updating an HTML progress bar with the estimated time remaining, to keep it simple.

When I visit the site in production, the progress bar works fine on:

  • my laptop’s Firefox
  • my laptop’s Chrome

But it won’t increment on:

  • my phone’s Firefox
  • my phone’s Safari
  • my laptop’s Safari

In Safari, for example, I can confirm that a console.log is firing 1x per second, so the JS is running. I thought it might be an issue with progress bar compatibility, so I just used a_div.insertAdjacentHTML('afterend', '<h3>foo</h3>'). Again, this works in Firefox/Chrome, but not in the others.

In all browsers, the form submits and the user is eventually brought to the next page.

Do some browsers not allow updating elements after submitting the form?

check if object element in array 1 exist in array 2?

consider this two array of objects :

const arr1 = [
    {id: 'parent1', title: 'product1', childProducts: [{id: 'child1', title: 'childProduct1'}]},
    {id: 'parent2', title: 'product2', childProducts: [{id: 'child2', title: 'childProduct2'}]},
];

const arr2 = [{id: 'child1', title: 'childProduct1'}];

I need to compare childProducts of arr 1 with arr 2 and somehow filter arr 1 like below:

const result = [{id: 'parent2', title: 'product2', childProducts: [{id: 'child2', title: 'childProduct2'}]}]

in other words, I need to return elements from arr1 that their childProducts are not in arr2 (whith help of loops).
how can I achieve this?

I made a to-do list using JavaScript. How do I remember the list items after refresh or exit and revisiting the page without deleting the items?

I have created a basic and unstyled to-do list using Javascript. I want the browser to remember the list items when I refresh the page or when I exit the page and revisit it.

I also want the user to be able to click an “X” or something to delete the list item from the browser’s memory and to forget it.

Here’s my code:

HTML:

<!DOCTYPE html>
<html lang="en">

<head>
    <title>My TO-DOs</title>
</head>

<body>
    <div id="header">
        <h1>My Todos</h1>

        <form>
            <label>Add an item:</label>
            <input type="text">

            <button type="submit">ADD</button>
        </form>
    </div>

    <ul id="itemList"></ul>
    <script src="main.js"></script>
</body>

</html>

JavaScript:

const form = document.querySelector('form');
const input = document.querySelector('input');

form.addEventListener('submit', function(e){
    e.preventDefault();

    if (input.value === '' || input.value === null) {
        alert('You cannot add a blank item.');
    } else{
    const listItem = document.createElement('li');
    const listItemText = document.createTextNode(input.value);
    listItem.appendChild(listItemText);
    

    const listElement = document.getElementById('itemList');
    listElement.appendChild(listItem)

    // Clear the input after adding an item
    input.value = '';
    input.focus();
}});

Here is a code snippet:

const form = document.querySelector('form');
const input = document.querySelector('input');

form.addEventListener('submit', function(e){
    e.preventDefault();

    if (input.value === '' || input.value === null) {
        alert('You cannot add a blank item.');
    } else{
    const listItem = document.createElement('li');
    const listItemText = document.createTextNode(input.value);
    listItem.appendChild(listItemText);
    

    const listElement = document.getElementById('itemList');
    listElement.appendChild(listItem)

    // Clear the input after adding an item
    input.value = '';
    input.focus();
}});
<!DOCTYPE html>
<html lang="en">

<head>
    <title>My TO-DOs</title>
</head>

<body>
    <div id="header">
        <h1>My Todos</h1>

        <form>
            <label>Add an item:</label>
            <input type="text">

            <button type="submit">ADD</button>
        </form>
    </div>

    <ul id="itemList"></ul>
    <script src="main.js"></script>
</body>

</html>

Cast to ObjectId failed for value … at path “author”

I’m fairly new in programming but I am following a udemy course that’s been great to me but I encountered an issue I’m having trouble solving. Whenever I node seed/index.js to add new latitudes and longitudes to the clustermap I’ve just added, I get this campground validation failed error. I’ve checked my models and they look okay to me. I don’t know what to do next at this point. Here’s my whole code, https://github.com/wcadz27/YelpCamp . Any help is greatly appreciated. Thank you very much

PDF field: Change State/Province name to abbreviation

I have a field in a PDF that is calculating the value of two fields: Billing City and Billing State/Province with a comma between:

event.value=this.getField("Billing City").value + ", " + this.getField("Billing State/Province").value;

The information is imported into a PDF with a txt file where the State/Province is written as the full name, but I would like the above field to use the abbreviation.

I have the state/province field as a dropdown with abbreviations as the export value, however it’s still calculating using the state/province full name. I tried this code but then the State/Province field gets stuck on the first option:

event.value = this.getField("Billing State/Province").valueAsString;

this.getField("Billing State/Province").setItems([["Alberta", "AB"], ["British Columbia", "BC"], ["Manitoba", "MB"], ["New Brunswick", "NB"], ["Newfoundland and Labrador", "NL"], ["Nova Scotia", "NS"], ["Northwest Territories", "NT"], ["Nunavut", "NU"], ["Ontario", "ON"], ["Prince Edward Island", "PE"], ["Quebec", "QC"], ["Saskatchewan", "SK"], ["Yukon Territories", "YT"]]);

Is there a different way to change the state/province name to abbreviations?