Error: Objects are not valid as a React child (found: object with keys {username}) [duplicate]

In my ReactJS application I have been trying to solve this problem for a very long time.

In a Users.js file Im fetching all the users from the database and storing it in a state called user. My goal is to render all these users by iterating through the list of users.

Here is my list of users that im getting from my backend:
list of users to be displayed

Then I am running a loop in the Users.js component and for every user, im rendering a User component

Here is my Users.js component:

import React, { useEffect, useState } from "react";
import User from "./User/User";

export default function Users() {
   const [users, setUsers] = useState([]);
   useEffect(() => {
       axios
           .get("http://localhost:8000/users")
           .then((res) => {
               console.log(res.data);
               setUsers(res.data);
           })
           .catch((err) => console.log(err));
   }, []);
   return (
       <div className="container">
           {users.map((user) => {
               console.log(user);
               return <User key={user.id} username={user.username} />;
           })}
       </div>
   );
}

here is my User.js component:

import React from "react";
import { Link } from "react-router-dom";

export default function User(props) {
    console.log("User.js component.");
    console.log(props.username);
    return (
        <div>
            <div className="card">
                <Link to="/">
                    <div className="card-body">
                        Use this kinda element to show user: {props}
                    </div>
                </Link>
            </div>
        </div>
    );
}

I expected everything to run properly but I got this error:

error

I researched a little bit about the error and found out that it is because im passing an object as a prop to a component. But when I checked the typeof user.id and typeof user.username which i was passing as a prop to the User component. I found that none of them (user.id and user.username) were objects. They were number and string respectively.

Please help me solve this.

Thanks!

How to get Scrollbar for left side of the Image/Div after it is scaled at the center

I’m centering an image using display:flex & justify-content:center
and using some zoom buttons to scale the image when they’re clicked.

The issue is that I’m not able to get a scroll bar to go to the Left Side of the image after it is scaled.

I checked about the scaling property and learned that it scales the (0,0) coordinates and possibly I’m trying to go the negative coordinates (https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/scale()#scaling_the_x_and_y_dimensions_together)

Is there anything i can do to go to have full access of the image after it is being scaled? (by full access i mean to the left/right/top/bottom)
Here is the fiddle for reference : https://jsfiddle.net/r9sdhjyz/1/

es6 import index.js by directory name

I’ve been looking around and can’t seem to find a clear answer on this.

Is it possible to import a an index.js file from a client directory using the directory name (omitting /index.js)? If so, how? This is a new project and I don’t really want to bundle my code at this point.

The node version is v17.1.0.

File structure

package.json
server.js
src/
  index.js
  utils/
    index.js

package.json

{
  "type": "module",
  "main": "server.js",
  "scripts": {
    "start": "nodemon --ignore src"
  },
  "devDependencies": {
    "express": "^4.17.1",
    "nodemon": "^2.0.14"
  }
}

server.js

import express from 'express'

express()
  .use(express.static('src'))
  .get('/', (_, res) => res.send(`
    <script type="module" src="index.js"></script>`))
  .listen(3000, () => console.log(`Running at http://localhost:3000`))

src/index.js

import { stuff } from './utils'

// Firefox: Loading module from “http://localhost:3000/utils/” 
// was blocked because of a disallowed MIME type (“text/html”).

I’ve tried running the app with node --experimental-specifier-resolution=node server.js and tried adding express.static.mime.define({'text/javascript': ['js']}) to server.js, but neither worked for me.

Working with jquery post request node js response

I am trying to send a jquery post request to node js.
I have a form, whose button has a click event listener and sends a jquery post request to the route “/login” and also attaches the data entered in the input fields. The node js works fine, but all the activities being done when the node js server gives some response back do not work. Here’s my javascript:

const loginCont = document.getElementById("loginCont");

loginCont.addEventListener("click", () => {
    const loginError = document.getElementById("login_error_box");
    const loginUser = document.getElementById("loginUsername").value;
    const loginPass = document.getElementById("loginPassword").value;

    $.post('/login',
        { username: loginUser, password: loginPass },
        function(data, status, jqXHR) { // Anything I do in this function doesn't get executed.
            loginError.classList.remove("hidden");
            loginError.innerHTML += `Login success`;
        }
    );
});

And here’s my server-side code (node js) :

var express = require('express');
var app = express();
var fs = require('fs');
var MongoClient = require('mongodb').MongoClient;
var bodyParser = require('body-parser')
app. use( bodyParser.json() );
app.use(bodyParser.urlencoded({ extended: true })); 

app.post('/login', function (req, res) {
  var user = req.body.username;
      pass = req.body.password;

  var myobj = { "user": user, "pass": pass };

  MongoClient.connect(mongo_profiles_url).then(function(db, err) {
    if (err) throw err;

    var dbo = db.db("PAL");
    dbo.collection("user-profiles").find(myobj).toArray(function(err, ob) {
      if (err) throw err;

      if (ob.length == 1) {
        var r = "success"
        res.writeHead(200, {'Content-Type': 'text'});
        console.log(` A person is trying to login with the following details (and is successful in doing so):
        • Username : ${user}
        • Password : ${pass}
        `);
      } else {
        var r = "fail"
        res.writeHead(200, {'Content-Type': 'text'});
        console.log(` A person is trying to login with the following details (but failed to do so):
        • Username : ${user}
        • Password : ${pass}
        `);
      }
      res.end(r);
    });
  });
});

app.listen(1000, function () {
    console.log("Server listening to http://localhost:1000");
});

Hope someone or the other will be able to help me out.

Thanks in advance!

How to call same api with different params on click of button in react native

I have made 3 different custom buttons:

<TouchableOpacity onPress={selectClosed}>
    <Text>Closed</Text>
</TouchableOpacity>

<TouchableOpacity onPress={selectPending}>
    <Text>Pending</Text>
</TouchableOpacity>

<TouchableOpacity onPress={selectComplete}>
    <Text>Complete</Text>
</TouchableOpacity>

and their onPress functions:

const selectClosed = () => {
    getShiftDetails.bind(null, 'closed');
};
const selectPending = () => {
    getShiftDetails.bind(null, 'pending');
};
const selectComplete = () => {
    getShiftDetails.bind(null, 'complete');
};

Below is how I am making my api call:

const getShiftDetails = useCallback(
    (
        page = 1,
        limit = 20,
        mode: 'pending' | 'complete' | 'closed' = 'complete',
    ) => {
            const payload = {
                page,
                limit,
                status: [mode],
            };
            ApiFunctions.post(apiUrl + '/shift', payload)
                .then(
                    // other stuff
                )
                .catch((err: any) => {
                    // other stuff
                });
    },
    [user],
);

By default my api call is being done with mode as complete. Now if I click on pending button then another api call should be made with mode as pending. But this is not happening. I am not sure where I went wrong.

my popup element will show up again after, i uncheck the radio and set all variable to undefine

i try set my variable to undefined again when user click button “hapus” then i click submit again, “alert” trigerred and show user need to fill all radio but then after click ok the popup show up

how make the pop up not show up and only show up when user fill radio ?
and why i need to click 2 times to run function when click submit ? how make it only need click 1 time?

here the the link for the page in case something wrong in snippet

test web

sry for my english,
here my code

let allData = ""

function inputData(data1, data2, data3, data4, data5) {
    let result;
    let result2;
    result = Number(data1) + Number(data2) + Number(data3) + Number(data4) + Number(data5);
    result2 = result / 5;
    return result2;
}

function prosesData(data1, data2, data3) {
    let result;
    let result2;
    result = Number(data1) + Number(data2) + Number(data3);
    result2 = result / 3;
    return result2
}

function outputData(data1, data2, data3, data4) {
    let result;
    let result2;
    result = Number(data1) + Number(data2) + Number(data3) + Number(data4);
    result2 = result / 4;
    return result2;
}


function hitungData(data1, data2, data3) {
    if (data1 >= 3 && data2 >= 3 && data3 >= 3) {
        allData = "Berkelanjutan"
        return allData;
    } else if ((data1 <= 3 && data2 <= 3) && (data3 > 3)) {
        allData = "Mandiri"
        return allData;
    } else if ((data1 >= 3 && data2 >= 3) && (data3 < 3)) {
        allData = "Berkembang"
        return allData;
    } else if (data1 < 3 && data2 < 3 && data3 < 3) {
        allData = "Dasar"
        return allData;
    } else if (data1 >= 3 || data2 >= 3 || data3 >= 3) {
        allData = "Dasar"
        return allData;
    } else {
        console.log("error");

    }
}

function panggilSemua() {
    //make variables from radio Input
    let input1 = document.querySelector('input[name="input-soal1"]:checked')?.value;
    let input2 = document.querySelector('input[name="input-soal2"]:checked')?.value;
    let input3 = document.querySelector('input[name="input-soal3"]:checked')?.value;
    let input4 = document.querySelector('input[name="input-soal4"]:checked')?.value;
    let input5 = document.querySelector('input[name="input-soal5"]:checked')?.value;
    if(input1 == undefined || input2 == undefined || input3 == undefined || input4 == undefined || input5 == undefined) {
        return alert("Data Input Masih Ada Yang Kosong")
    }

    //Make Variable from radio proses
    let proses1 = document.querySelector('input[name="proses-soal1"]:checked')?.value;
    let proses2 = document.querySelector('input[name="proses-soal2"]:checked')?.value;
    let proses3 = document.querySelector('input[name="proses-soal3"]:checked')?.value;
    if(proses1 == undefined || proses2 == undefined || proses3 == undefined) {
        return alert("Data Proses Masih Ada Yang Kosong")
    }

    //make variables from radio output
    let output1 = document.querySelector('input[name="output-soal1"]:checked')?.value;
    let output2 = document.querySelector('input[name="output-soal2"]:checked')?.value;
    let output3 = document.querySelector('input[name="output-soal3"]:checked')?.value;
    let output4 = document.querySelector('input[name="output-soal4"]:checked')?.value;
    if(output1 == undefined || output2 == undefined || output3 == undefined || output4 == undefined) {
        return alert("Data Output Masih Ada Yang Kosong")
    }

    let resultInput = inputData(input1, input2, input3, input4, input5);
    let resultProsses = prosesData(proses1, proses2, proses3);
    let resultOutput = outputData(output1, output2, output3, output4);

    resultFinal = hitungData(resultInput, resultProsses, resultOutput);
    document.getElementById('submit-btn').addEventListener('click', function(){
        document.querySelector('.showdata').innerHTML = "Klasifikasi :" + " " + resultFinal;
        document.querySelector('.bg-pop').style.display = "flex"
        location.href = "#showdata"
    });

    document.querySelector('.close-btn').addEventListener('click',
    function(){
        document.querySelector('.bg-pop').style.display = "none"
    });
}

function hapusData() {
        input1 = undefined;
        input2 = undefined;
        input3 = undefined;
        input4 = undefined;
        input5 = undefined;
        proses1 = undefined;
        proses2 = undefined;
        proses3 = undefined;
        output1 = undefined;
        output2 = undefined;
        output3 = undefined;
}
@import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@500&display=swap');
* {
    box-sizing: border-box;
    font-family: 'Quicksand', sans-serif, monospace;
    scroll-behavior: smooth;
}

body {
    margin: 0;
    padding: 0;
    font-size: 16px;
    position: relative;
} 

header {
    display: inline;
}

main {
    padding: 20px;
    overflow: auto;
}

h2 {
    color: #00a2c6;
}

h3 {
    color: #00a2c6;
}

footer {
    padding: 20px;
    color: white;
    background-color: #00a2c6;
}

.jumbotron {
    font-size: 20px;
    padding: 60px;
    background-color: #00c8eb;
    text-align: center;
    color: white;
}

nav {
    background-color: #00a2c6;
    padding: 5px;
    position: -webkit-sticky;
    position: sticky;
    top: 0;
}

nav a {
    font-size: 18px;
    font-weight: 400;
    text-decoration: none;
    color: white;
}

nav a:hover {
    font-weight: bold;
}

nav li {
    display: inline;
    list-style-type: none;
    margin-right: 20px;
}

footer {
    padding: 20px;
    color: white;
    background-color: #00a2c6;
    text-align: center;
    font-weight: bold;
}

.card {
    box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.226);
    border-radius: 10px;
    padding: 20px;
    margin-top: 20px;
}

.headerbox {
    border-bottom: 1px solid black;
    padding-bottom: 10px;
    text-align: center;
    font-size: 2em;
    text-transform: uppercase;
    font-weight: bold
}

#content {
    width: 75%;
}

.allButton {
    text-align: center;
}

.allButton .button {
    padding: 20px 30px;
    border-radius: 5px;
    border: 1px solid white;
    font-weight: bold;
}

.allButton .button:hover {
    background-color: #00c8eb;
    color: white;
    font-weight: bold;
    cursor: pointer;
}

.bg-pop {
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.7);
    position: absolute;
    top: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    display: none;
}

.pop-content {
    width: 500px;
    height: 300px;
    background-color:white;
    border-radius: 10px;
    padding: 50px;
    text-align: center;
    border: 1px solid black;
    margin: 0 20px;
}

.showdata {
    font-size:20px;
}

.close-btn {
    padding: 20px 30px;
    font-weight: bold;
    border: 1px solid white;
    border-radius: 10px;
}

.close-btn:hover {
    background-color:#00c8eb;
    color: white;
}

/* @media screen and (max-width: 992px) {
    #content {
        width: 100%;
        padding: 0;
    }
} */
<html lang="id">
<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">
    <link rel="stylesheet" href="assets/bootstrap/css/bkkbn_css.css">
    <script src="https://kit.fontawesome.com/073910e859.js" crossorigin="anonymous"></script>
    <title>Simulasi Klasifikasi Kampung KB</title>
</head>

<body>
    <header>
        <div class="jumbotron">
            <h1>Simulasi Klasifikasi Kampung KB</h1>
        </div>
        <nav>
            <ul>
                <li><a href="#">Home</a></li>
                <li><a href="#">Contact</a></li>
                <li><a href="#">About</a></li>
            </ul>
        </nav>
    </header>
    <main>
        <div id="#content">
            <form>
                <div class="databox">
                    <div class="card">
                        <div class="box input">
                            <div class="input headerbox">Input</div>
                            <div class="input-content">
                                <p>Keberadaan Pokja (kepemilikan pokja, SK Pokja, Pokja terlatih, sosialisasi pokja)</p>
                                <input type="radio" name="input-soal1" id="input-radio1" value="1">
                                <label for="radio">1</label>
                                <input type="radio" name="input-soal1" id="input-radio2" value="2">
                                <label for="radio">2</label>
                                <input type="radio" name="input-soal1" id="input-radio3" value="3">
                                <label for="radio">3</label>
                                <input type="radio" name="input-soal1" id="input-radio4" value="4">
                                <label for="radio">4</label>
                                <br>
                                <br>
                                <p>Sumber dana (APBN, APBD, Dana Desa, CSR, swadaya masy, Hibah, Lainnya)</p>
                                <input type="radio" name="input-soal2" id="input-radio5" value="1">
                                <label for="radio">1</label>
                                <input type="radio" name="input-soal2" id="input-radio6" value="2">
                                <label for="radio">2</label>
                                <input type="radio" name="input-soal2" id="input-radio7" value="3">
                                <label for="radio">3</label>
                                <input type="radio" name="input-soal2" id="input-radio8" value="4">
                                <label for="radio">4</label>
                                <br>
                                <br>
                                <p>Kepemilikan poktan (BKB, BKR, BKL, UPPKS, dan PIKR)</p>
                                <input type="radio" name="input-soal3" id="input-radio9" value="1">
                                <label for="radio">1</label>
                                <input type="radio" name="input-soal3" id="input-radio10" value="2">
                                <label for="radio">2</label>
                                <input type="radio" name="input-soal3" id="input-radio11" value="3">
                                <label for="radio">3</label>
                                <input type="radio" name="input-soal3" id="input-radio12" value="4">
                                <label for="radio">4</label>
                                <br>
                                <br>
                                <p>Ada sarana tempat sektereiatan dan sarana rumah data</p>
                                <input type="radio" name="input-soal4" id="input-radio13" value="1">
                                <label for="radio">1</label>
                                <input type="radio" name="input-soal4" id="input-radio14" value="2">
                                <label for="radio">2</label>
                                <input type="radio" name="input-soal4" id="input-radio15" value="3">
                                <label for="radio">3</label>
                                <br>
                                <br>
                                <p>Keberadaan PKB/PLKB dan Regulasi</p>
                                <input type="radio" name="input-soal5" id="input-radio16" value="1">
                                <label for="radio">1</label>
                                <input type="radio" name="input-soal5" id="input-radio17" value="2">
                                <label for="radio">2</label>
                                <input type="radio" name="input-soal5" id="input-radio18" value="3">
                                <label for="radio">3</label>
                            </div>
                        </div>
                    </div>
                    <div class="card">
                        <div class="box proses">
                            <div class="proses headerbox">Proses</div>
                            <div class="proses-content">
                                <p>Penggunaan data untuk perencaan antara lain Data PK, Data Rutin, Data podes, Data
                                    Sektoral,
                                    Sumber Data lainnya</p>
                                <input type="radio" name="proses-soal1" id="proses-radio1" value="1">
                                <label for="radio">1</label>
                                <input type="radio" name="proses-soal1" id="proses-radio2" value="2">
                                <label for="radio">2</label>
                                <input type="radio" name="proses-soal1" id="proses-radio3" value="3">
                                <label for="radio">3</label>
                                <input type="radio" name="proses-soal1" id="proses-radio4" value="4">
                                <label for="radio">4</label>
                                <br>
                                <br>
                                <p>Mekanisme operasional antara lain : rapat perencaan kegiatan koordinasi dengan litas
                                    sektoral
                                    melakukan sosialisasi kegiatan melakukan monev, membuat laporan.</p>
                                <input type="radio" name="proses-soal2" id="proses-radio5" value="1">
                                <label for="radio">1</label>
                                <input type="radio" name="proses-soal2" id="proses-radio6" value="2">
                                <label for="radio">2</label>
                                <input type="radio" name="proses-soal2" id="proses-radio7" value="3">
                                <label for="radio">3</label>
                                <input type="radio" name="proses-soal2" id="proses-radio8" value="4">
                                <label for="radio">4</label>
                                <br>
                                <br>
                                <p>Intervansi lintas sektoral : Keterlibatan sektor lain dalam pelaksaan kegiatan</p>
                                <input type="radio" name="proses-soal3" id="proses-radio9" value="1">
                                <label for="radio">1</label>
                                <input type="radio" name="proses-soal3" id="proses-radio10" value="2">
                                <label for="radio">2</label>
                                <input type="radio" name="proses-soal3" id="proses-radio11" value="3">
                                <label for="radio">3</label>
                                <input type="radio" name="proses-soal3" id="proses-radio12" value="4">
                                <label for="radio">4</label>
                                <br>
                                <br>
                            </div>
                        </div>
                    </div>
                    <div class="card">
                        <div class="box output">
                            <div class="output headerbox">Output</div>
                            <div class="output-content">
                                <p>Partisipasi keluarga / remaja dalam kegiatan Poktan BKB, BKR, BKL, PIK-R dan UPPKS
                                </p>
                                <input type="radio" name="output-soal1" id="output-radio1" value="1">
                                <label for="radio" id="wkwk">1</label>
                                <input type="radio" name="output-soal1" id="output-radio2" value="2">
                                <label for="radio">2</label>
                                <input type="radio" name="output-soal1" id="output-radio3" value="3">
                                <label for="radio">3</label>
                                <input type="radio" name="output-soal1" id="output-radio4" value="4">
                                <label for="radio">4</label>
                                <br>
                                <br>
                                <p>Capaian CPR kontrasepsi modern</p>
                                <input type="radio" name="output-soal2" id="output-radio5" value="1">
                                <label for="radio">1</label>
                                <input type="radio" name="output-soal2" id="output-radio6" value="2">
                                <label for="radio">2</label>
                                <input type="radio" name="output-soal2" id="output-radio7" value="3">
                                <label for="radio">3</label>
                                <input type="radio" name="output-soal2" id="output-radio8" value="4">
                                <label for="radio">4</label>
                                <br>
                                <br>
                                <p>Capaian MKJP kontrasepsi mix</p>
                                <input type="radio" name="output-soal3" id="output-radio9" value="1">
                                <label for="radio">1</label>
                                <input type="radio" name="output-soal3" id="output-radio10" value="2">
                                <label for="radio">2</label>
                                <input type="radio" name="output-soal3" id="output-radio11" value="3">
                                <label for="radio">3</label>
                                <input type="radio" name="output-soal3" id="poutput-radio12" value="4">
                                <label for="radio">4</label>
                                <br>
                                <br>
                                <p>Persentase PUS tidak berKB / unmet need</p>
                                <input type="radio" name="output-soal4" id="output-radio13" value="1">
                                <label for="radio">1</label>
                                <input type="radio" name="output-soal4" id="output-radio14" value="2">
                                <label for="radio">2</label>
                                <input type="radio" name="output-soal4" id="output-radio15" value="3">
                                <label for="radio">3</label>
                                <input type="radio" name="output-soal4" id="output-radio16" value="4">
                                <label for="radio">4</label>
                                <br>
                                <br>
                            </div>
                        </div>
                    </div>
                    <div class="card">
                        <div class="allButton">
                            <!-- <div class="showdata" style="margin-bottom: 20px;">HASIL DISINI</div> -->
                            <input class="button" id="hapus-btn" type="reset" onclick="hapusData()" value="hapus">
                            <input class="button" id="submit-btn" type="button" onclick="panggilSemua()" value="submit">
                        </div>
                    </div>
                </div>
            </form>
        </div>
    </main>
    <footer>
        <p>BKKBN</p>
        <p id="tanggal"></p>
    </footer>
    <div class="bg-pop">
        <div class="pop-content" id="showdata">
            <i class="far fa-check-circle fa-4x" style="color: rgb(93, 223, 76)"></i>
            <p class="showdata"></p>
            <button class="close-btn">Tutup</button>
        </div>
    </div>
</body>
<script src="assets/js/bkkbn_js.js"></script>
<script>
    const tanggal = new Date().getFullYear();
    document.getElementById("tanggal").innerHTML = "&copy;" + " " + tanggal;
</script>

</html>

Custom filename for BLOB URL

I am implementing this functionality in ReactJS, Application generated blob url but I want to replace it with my custom file name. I tried but unfortunately was not able to achieve my goal could someone please help me thanks.

  const blob = new Blob([res.data], { type: 'application/pdf' })
    const blobUrl = URL.createObjectURL(blob)
    var fileLink = document.createElement('a')
    fileLink.href = fileLink

    // it forces the name of the downloaded file
    fileLink.download = 'pdf_name.pdf'

    // triggers the click event
    fileLink.click()

I implemented this code but when it get downloaded it showing Failed - no file

Scroll two DIVs different height with a parallax-like effect

I’ve been scanning the web for a simple solution possibly without using a 3rd party library.

I have a Section with two DIVs that are placed side-by-side that have different heights. WhatI want to achieve is as I scroll down the web page, when I reach this Section the DIV on the left remains fixed until the right-hand-side DIV reaches the bottom and then the whole page continues scrolling down similar to some Parallax effects.

I like the Section’s height to be limited to 100vh and the solution should work on different devices except Cellphone.

I found ScrollMagic but it looks like you should know the heights before hand and in my case the DIV on the right has content that can change over time.

Any help is greatly appreciated.

Changing state on redux-saga causes infinite loop inside component

I am trying to redirect user after successful login but changing state in saga is causing an infinite loop.

In my component I am using useSelector to listen to changes in isValidSession from store. If isValidSession changes to true, I want to redirect user to another page. However, when isValidSession is changed, my component keeps re-rendering in an infinite loop.

component

import { Link, useLocation } from 'react-router-dom'
import { Redirect } from 'react-router'

import MainLayout from '../../../layouts/MainLayout'
import { Typography, Alert, Row, Col, Divider } from 'antd'
import LoginForm from './LoginForm'

import { useDispatch, useSelector } from 'react-redux'
import * as loginActions from './Login.action'

const { Title } = Typography

export default function Login() {

    const dispatch = useDispatch()

    const { isValidSession, error } = useSelector((state) => state.login)

    const location = useLocation()

    let { from } = location.state || { from: { pathname: '/templates' } }

    const handleLogin = ({ email, password }) =>
        {
            dispatch(loginActions.authenticate({ email, password }))
        }

    const getAPIError = (error) =>
        error.status == 401
            ? 'Invalid username or password'
            : 'Something went wrong'

    if (isValidSession) return <Redirect push to={from.pathname} />

    return (
        <MainLayout>
            <Row align='stretch' className='vh-100'>
                <Col xs={24} md={12} lg={10} xl={8} xxl={6} className='bg--white'>
                    <div className='d-flex align-items-center h-100 p-5'>
                        <div id='login' className='w-100'>
                        
                            <Title level={3}>Welcome Back!</Title>

                            {/* ERROR MESSAGE */}
                            {error ? (
                                <Alert
                                    message={getAPIError(error)}
                                    showIcon
                                    type='error'
                                    className='mb-2'
                                />
                            ) : (
                                ''
                            )}

                            {/* FORM */}
                            <LoginForm onFinish={handleLogin} />

                            <Divider />

                            {/* ADDITIONAL LINKS */}
                            <div className='text-center'>
                                <p>
                                    Don't have an account yet?{' '}
                                    <Link
                                        to={{ pathname: '/register', state: { from: location } }}
                                    >
                                        Sign up
                                    </Link>
                                </p>
                                <Link
                                    to={{
                                        pathname: '/auth/recover-password',
                                        state: { from: location },
                                    }}
                                >
                                    Forgot your password?
                                </Link>
                            </div>
                        </div>
                    </div>
                </Col>
            </Row>
        </MainLayout>
    )
}

In my reducer, for action types.LOGIN_SUCCESS, I am making isValidSession to true.

reducer

const loginReducer = (state = initialState, action) => {
    switch (action.type) {
        case types.LOGIN_REQUESTING: {
            return {
                ...state,
                submitted: false,
            }
        }
        case types.LOGIN_SUCCESS: {
            return {
                ...state,
                submitted: true,
                successful: true,
                isValidSession: true,
            }
        }
        case types.LOGIN_ERROR: {
            const { error } = action
            return {
                ...state,
                error,
                submitted: false,
                successful: false,
                isValidSession: false,
            }
        }
        case types.UPDATE_LOGIN_CREDENTIAL: {
            const { login } = action
            return {
                ...state,
                login: {
                    ...state.login,
                    ...login,
                },
            }
        }
        case types.IS_LOGGINGIN: {
            const { isLoggingIn } = action
            return {
                ...state,
                isLoggingIn,
            }
        }
        default:
            return {
                ...state,
            }
    }
}

In my saga code, you can see that I am doing yield put({ type: types.LOGIN_SUCCESS }) to change isValidSession to true. 

saga

function* authenticateSage(payload) {
    try {
        alert('authenticateSage')

        const response = yield call(authService.login, payload.login)
        const { profile, account } = response

        yield put({ type: types.LOGIN_SUCCESS })
    } catch (error) {
        yield put({
            type: types.LOGIN_ERROR,
            error: { status: error.status, message: error.data?.message },
        })
    }
}

export default function* watchAuthentication() {
    yield takeLatest(types.LOGIN_REQUESTING, authenticateSage)
}

Bootstrap 3.3.7 dropdown menu not working on mobile

We populating our dropdowns from a JSON file, but for some reason, it’s not working on mobile. Except for the li anchors, I’m following the guidelines from the Bootstrap 3.3.7 documentation: https://getbootstrap.com/docs/3.3/components/#dropdowns.

I also added this, but the issue persists on mobile devices:

$('.dropdown-backdrop').css({display: 'none'});

What could be causing this? Here’s my dropdown code.

<div class="dropdown w-100 open" id="attrib">
  <button data-device="Umbra 501" class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
    Economy
    <span class="glyphicon glyphicon-menu-down"></span>
  </button>
  <ul class="dropdown-menu dropdown-menu-right">
    <li><a data-filter-dropdown="Small">Small</a></li>
    <li><a data-filter-dropdown="Medium">Medium</a></li>
    <li><a data-filter-dropdown="Large">Large</a></li>
    <li><a data-filter-dropdown="Xlarge">Xlarge</a></li>
  </ul>
</div>

Using Javascript functions with a button in Handlebars

I have a handlebars project with the following structure:

Project
 |
 +-- server.js
 +-- package.json
 +-- package-lock.json
 |    
 +-- public
 |  |  
 |  |-- css
 |      |
 |      + -- style.css
 |
 +-- views
 |  |  
 |  |-- layouts
 |  |   |
 |  |   + -- main.handlebars
 |  +-- index.handlebars

In my server.js file, I created the app to run on localhost:3000, as well as serve the index.handlebars at /. I understand how to grab information from an api, so just to learn how to navigate displaying data from an API in a handlebars application, I created a GetInsult(); function to retrieve a random insult from an API I found online (purely for learning purposes). I grab the data with the function, and then pass the data to the res.render() function. You can see how this works in my server.js file:

//import modules
import dotenv from 'dotenv';
dotenv.config();

import http from 'http';
import path from 'path';
import { dirname } from 'path';
import express from 'express';
import { engine } from 'express-handlebars';
import axios from 'axios';


//other variables
const port = process.env.PORT;
const hostname = process.env.HOSTNAME;
const __dirname = path.resolve();

//store data in variable
var insult = await GetInsult();


const app = express();

//Create http server to run and listen on localhost:3000
var server = http.createServer(app).listen(port, hostname, () => {
    console.log(`Server is running at http://${hostname}:${port}`);
})

app.engine('handlebars', engine());
app.set('view engine', 'handlebars')
app.set('views', './views')

//Use Static Files
app.use('/public', express.static(__dirname + '/public'));
app.use('/css', express.static(path.join(__dirname, 'node_modules/bootstrap/dist/css')));
app.use('/js', express.static(path.join(__dirname, 'node_modules/bootstrap/dist/js')));
app.use('/js', express.static(path.join(__dirname, 'node_modules/jquery')));

app.get('/', (req, res) => {
    res.render('index' , {insult})
});



export async function GetInsult() {
    var response = await axios('https://insult.mattbas.org/api/insult')
    var data = response.data
    return data
}

console.log(insult)

Then in my index.handlebars file, I can successfully display the insult like so:

<main>
    <div style="text-align: center;">
        <h1 id="insult">{{insult}}</h1>
        <button id="insult-button" class="btn btn-dark">Get New Insult</button>
    </div>
</main>

I’m having trouble figuring out how to add the GetInsult(); functionality to the button I have underneath the <h1>{{insult}}</h1> tags. I’ve tried numerous ways and feel like I’m missing something simple. I would like the button to execute the GetInsult(); function and display the new insult that is retrieved from the API. I’m not sure if I need to house the function elsewhere and call it from another file, or if it’s even possible with an asynchronous function. Any guidance would be appreciated. Thank you!

Phaser 3 Tweens with changing variable value

I’m building an HTML5 game with Phaser 3. I have a counter tween that I add to the scene upon a certain if condition being met on click of a game object. (It is a text value that flashes red if the card’s maximum stat value is lower than the player’s value of that stat.)

First, I set the variable based on which card was clicked:

if (this == action1_card) {
                action = action1
                energy_cost = action1_energy_cost
                max_suspicion = action1_suspicion_threshold
                selected_card = action1_card_selected
} else if (this == action2_card) {
                action = action2
                energy_cost = action2_energy_cost
                max_suspicion = action2_suspicion_threshold
                selected_card = action2_card_selected
}

Once I have the values I want (max suspicion is the relevant variable in this case), I then apply the flashing color animation to it if the condition is met.

if (action.suspicion_threshold < game_data.player.stats.suspicion) {
    t.tweens.addCounter({
        from: 0,
        to: 100,
        duration: 250,
        repeat: 1,
        yoyo: true,
        ease: Phaser.Math.Easing.Sine.InOut,
        onUpdate: function(tween) {
            const value = Math.floor(tween.getValue());
            const colorObject = Phaser.Display.Color.Interpolate.ColorWithColor(
                                Phaser.Display.Color.ValueToColor('#000000'),
                                Phaser.Display.Color.ValueToColor('#FF0000'),
                                100,
                                value
                            )
            const color = Phaser.Display.Color.RGBToString(colorObject.r, colorObject.g, colorObject.b)
            max_suspicion.setColor(color);
    }
});

The issue is that, if I was to click on card 1 and then card 2 before the animation was finished on card 1, the animation from card 1’s text would resume on card 2. This makes sense, as the variable “max_suspicion” was reassigned to the text object on card 2, and the tween’s onUpdate function is continuing as it should.

How do I either:

1) prevent this from being reassigned (e.g. setting max_suspicion to permanently represent card 1’s text object for the scope of the tween)

or

2) reset card 1’s value to it’s original color and end the tween prematurely so it doesn’t carry over to card 2?

I will gladly clarify anything as needed. Thank you so much for any help on this!

How can javascript extract specified key value from json blob with many nested values?

I have an https query which returns a json blob in the following format:

{
"metric_data": {
    "from": "2021-12-09T01:25:32+00:00",
    "to": "2021-12-09T01:55:32+00:00",
    "metrics_not_found": [],
    "metrics_found": [
        "Mobile/Crash/All"
    ],
    "metrics": [
        {
            "name": "Mobile/Crash/All",
            "timeslices": [
                {
                    "from": "2021-12-09T01:24:00+00:00",
                    "to": "2021-12-09T01:54:00+00:00",
                    "values": {
                        "call_count": 5
                    }
                }
            ]
        }
    ]
}

}

I want to find and extract the value for call_count. What is the best way to do that with Javascript? The following code will actually print out all the json values, including the call_count but all my efforts to just grab the value for call_count are failing.

var json = `{
"metric_data": {
    "from": "2021-12-09T01:25:32+00:00",
    "to": "2021-12-09T01:55:32+00:00",
    "metrics_not_found": [],
    "metrics_found": [
        "Mobile/Crash/All"
    ],
    "metrics": [
        {
            "name": "Mobile/Crash/All",
            "timeslices": [
                {
                    "from": "2021-12-09T01:24:00+00:00",
                    "to": "2021-12-09T01:54:00+00:00",
                    "values": {
                        "call_count": 5
                    }
                }
            ]
        }
    ]
}
}`;
    
    // Convert a JSON object to a Javascript object
var obj = JSON.parse(json);

// This function prints nested values
function printValues(obj) {
    for(var k in obj) {
        if(obj[k] instanceof Object) {
            printValues(obj[k]);
        } else {
            document.write(obj[k] + "<br>");
        };
    }
};

// Printing all the values from the resulting object
printValues(obj);

document.write("<hr>");
    
    // This is where I fail as I try to print a single value.
    document.write(obj["metrics"]["call_count"] + "<br>");

Any feedback would be much appreciated!

p5js clipping mask equivalent?

I have a super simple script that creates a circle with alternating “slice” colors

let slices = 12;


function setup() {
  createCanvas(400, 400);
  noStroke();
}

function draw() {
  background(220);
  translate(width/2, height/2);
  
  let inc = TWO_PI/slices;
  let c = 0
  for (let i = 0; i < TWO_PI+inc; i+=inc) {
    if (c % 2 == 0) {
      fill('white')
    } else {
      fill('black')
    }
    arc(0, 0, width/2, width/2, i, i+inc);
    c++
  } 
}

How can I do this same thing but with a square? That is, I want the alternating slice colors but encapsulated in a square rather than a circle. I am not sure how to do this since I used arc() to create the slices. Is there some way I can create a mask or something? Or is there an easy solution to my problem?