RTK Query set token inside cookies but it is not having any effect

I started learning RTK Query few days ago and I have been enjoying it cool features and simplicity, so I decided to switch from useContext to RTK Query in the project I’m building with Next.js and a custom server using Node.js and express. In this project, I made an api route for login and signup which would be hit by using RTK Query and Axios with the help of custom axios base query RTK Query provided. The login and signup api endpoints already had a logic to store token inside the cookies storage. I use RTK Query with axios to post user request so they can get a response of their token store in cookies storage. This logic of storing user token in the cookies works well with useContext and axios.
But the logic didnot work as expected while using RTK Query, and these are results:

  • The token was set in the cookies storage but I get a response status of 401.
  • When user submit their credentials in the login or signup page, they are supposed to be redirected to profile page with their details being display since I made use of useQuery to fetch user profile. But the data did not display. Which means the token stored is not effective.
  • I’m unable to get the user information even though the token had been stored in the cookies.
  • Whenever I click on a link to redirect me to a particular route, useQuery didnot fetch anything and when I go back to profile, the user details will be fetched and display but when I refresh the page again, no data will be dsiplay
  • Whenever a get request was successful at the first time, I alway lose the data whenever I refresh the page.
  • All these issues only happens to routes that are protected with middleware in the backend and the middleware is to verify the token. But I have no issue with reloading a page which data that is not protected in the backend.
  • I also have a middleware in my backend for verifying and checking if token is true in the cookie to check if user is authenticated, if it is false, user should be directed to the login page in the frontend. The logic for fetching and check if data is true is inside HOC component which was wrapped with protected route, but whenever the data value is false, am still able to go to any route in the frontend instead of redirecting me to login page. And when I log the data to the console I recieve the correct data.
  • Removing token from cookie works successfully.

Note: Backend code isrunning fine as it was tested with thunder client and everything works fine when using it with useContext.
Here is my login api route.

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

const router = require("express").Router();
const { body, validationResult } = require("express-validator");
const User = require("../../Model/UserSchema");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcryptjs");

router.post(
  "/login",
  [
    body("email", "Email is required").isEmail(),
    body("password", "At least 6 characters").exists(),
  ],
  async (req, res) => {
    const errors = validationResult(req);

    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    const { email, password } = req.body;
    try {
      const existingUser = await User.findOne({ email });

      if (!existingUser)
        return res
          .status(401)
          .json({ errors: [{ msg: "Wrong email or password" }] });

      const passwordCorrect = await bcrypt.compare(
        password,
        existingUser.password
      );

      if (!passwordCorrect) {
        return res.status(401).json({ msg: "Wrong email or password" });
      }

      const token = jwt.sign(
        { user: existingUser._id },
        process.env.JWT_SECRET
      );

      //send cookies in httpOnly

      res.cookie("token", token, {
        httpOnly: true,
        sameSite: "strict",
      }).send;
      res.status(200).send("Login Successful");
    } catch (err) {
      res.status(400).json("Bad Request");
    }
  }
);

module.exports = router;

The register api route is similar with the login route.

Here is the code for my middleware for storing cookies with user id

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

const jwt = require("jsonwebtoken");

function auth(req, res, next) {
  try {
    const token = req.cookies.token;

    if (!token) {
      return res.status(401).json({ msg: "Unauthorized" });
    }

    const verified = jwt.verify(token, process.env.JWT_SECRET);

    req.user = verified.user;

    next();
  } catch (err) {
    console.log(err);
    res.status(401).res.json({ msg: Unauthorized });
  }
}

<!-- begin snippet: js hide: false console: true babel: false -->
module.exports = auth;

Here is the middleware for checking if token is true in cookies

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

const jwt = require("jsonwebtoken");
const router = require("express").Router();

router.get("/auth", (req, res) => {
  try {
    const token = req.cookies.token;

    if (!token) {
      return res.json(false);
    }
    jwt.verify(token, process.env.JWT_SECRET);

    res.send(true);
  } catch (err) {
    res.json(false);
  }
});

module.exports = router;

Here is my AxiosBaseQuery and createApi

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

import axios from "axios";
import { createApi } from "@reduxjs/toolkit/query/react";


const axiosBaseQuery =
  ({ baseUrl } = { baseUrl: "" }) =>
  async ({ url, method, data }) => {
    try {
      const result = await axios({ url: baseUrl + url, method, data });
      return { data: result.data };
    } catch (axiosError) {
      let err = axiosError;
      return {
        error: { status: err.response?.status, data: err.response?.data },
      };
    }
  };


export const fetcherApi = createApi({
  reducerPath: "fetcherApi",
  baseQuery: axiosBaseQuery({
    baseUrl: "http://localhost:5000/",
  }),
  tagTypes: ["User"],
  endpoints(build) {
    return {
      //________Authentication
      registerUser: build.mutation({
        query: (form) => ({
          url: "register",
          method: "post",
          data: form,
        }),
        invalidatesTags: ["User"],
      }),

      loginUser: build.mutation({
        query: (form) => ({
          url: "login",
          method: "post",
          data: form,
        }),
        invalidatesTags: ["User"],
      }),

      getAuth: build.query({
        query: () => ({ url: "auth", method: "get" }),
      }),

      //__________User
      updateUserName: build.mutation({
        query: (...rest) => ({
          url: "update-user",
          method: "put",
          data: rest,
        }),
        invalidatesTags: ["User"],
      }),

      getUser: build.query({
        query: () => ({ url: "user", method: "get" }),
        providesTags: ["User"],
      }),

      //__________Profile
      postProfile: build.mutation({
        query: (form) => ({
          url: "login",
          method: "post",
          data: form,
        }),
      }),

      getAllProfiles: build.query({
        query: () => ({ url: "all-profiles", method: "get" }),
      }),

      getUserProfile: build.query({
        query: () => ({ url: "profile/me", method: "get" }),
      }),

      //___________Car
      postCar: build.mutation({
        query: (form) => ({
          url: "new-car",
          method: "post",
          data: form,
        }),
      }),

      putCar: build.mutation({
        query: ({ id, ...rest }) => ({
          url: `update-car/{id}`,
          method: "put",
          data: { rest },
        }),
      }),

      getAllCars: build.query({
        query: () => ({ url: "all-cars", method: "get" }),
      }),

      getCarById: build.query({
        query: (id) => ({ url: `onecar/${id}`, method: "get" }),
      }),

      getAllUserCars: build.query({
        query: () => ({ url: "my-car", method: "get" }),
      }),
    };
  },
});

export const {
  // ______Authentication______
  useGetAuthQuery,
  useRegisterUserMutation,
  useLoginUserMutation,
  //_______User_________
  useUpdateUserNameMutation,
  useGetUserQuery,
  //_____Profile_________
  useGetUserProfileQuery,
  useGetAllProfilesQuery,
  usePostProfileMutation,
  //_____Car____________
  usePostCarMutation,
  usePutCarMutation,
  useGetAllCarsQuery,
  useGetCarByIdQuery,
  useGetAllUserCarsQuery,
} = fetcherApi;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

import Layout from "@/components/Layout";
import Image from "next/image";
import { FaDollarSign } from "react-icons/fa";
import Link from "next/link";
import { FiEdit } from "react-icons/fi";
import Authorization from "@/HOC/Authorization";
import {
  useGetUserProfileQuery,
  useGetUserQuery,
} from "@/store/ReduxStore/fetcherApi";
import MyCars from "@/components/MyCars";

function Profile() {
  const { data: profileData } = useGetUserProfileQuery();
  const { data: userData } = useGetUserQuery();

  return (
    <Layout>
      <div className="flex items-center justify-center mt-8 mx-auto w-4/5 ">
        {/* Card code block start */}
        <div className="bg-gray-300 shadow rounded-lg">
          <div className="relative ">
            <button className="w-full">
              <div className="coverpicstwo">
                <p className="text-xs text-gray-100">Change Cover Photo</p>
                <div className="ml-2 text-gray-100">
                  <FiEdit />
                </div>
              </div>
              <Image
                className="h-1/6 shadow rounded-t w-full object-cover object-center"
                src="/assets/images/d17.jpg"
                alt="profile"
                width={10000}
                height={2000}
              />
            </button>
            <button className="roundedprofile">
              <Image
                className="w-full h-full z-10 overflow-hidden object-cover rounded-full"
                src="/assets/images/d17.jpg"
                alt="profile-image"
                layout="fill"
              />
            </button>
          </div>
          <div className="px-5 xl:px-10 pb-10 mt-2">
            <div className="flex justify-center xl:justify-end w-full pt-16 xl:pt-5"></div>
            <div className="pt-3 xl:pt-5 flex flex-col xl:flex-row items-start xl:items-center justify-between">
              <div className="xl:pr-16 w-full xl:w-2/ mb-6 ">
                <div className="profileidentity">
                  <h2 className="profilename">{userData?.name}</h2>
                  <div className="profilestatus">
                    {profileData ? (
                      <p>{profileData.businessStatus}</p>
                    ) : (
                      <p>Buyer</p>
                    )}
                  </div>
                </div>
                <div className="profiledescription ">
                  {profileData ? (
                    <p>{profileData.description}</p>
                  ) : (
                    <p>Setup description</p>
                  )}
                </div>
              </div>

              <div className="workingstatusone">
                <div className="workingstatustwo">
                  <Link href="/new-car" passHref>
                    <button className="workingstatusthree">
                      <span>
                        <FaDollarSign className="text-xl mr-1" />
                      </span>
                      Sell
                    </button>
                  </Link>
                  <div className="availablestatus">
                    {profileData ? (
                      <p>{profileData.availability}</p>
                    ) : (
                      <p>Available</p>
                    )}
                  </div>
                </div>
                <div className="profilecontactbutton">
                  <Link
                    href="/profile-setup"
                    onClick={() => {
                      userNameHandler();
                      profileHandler();
                    }}
                    passHref
                  >
                    Contact || Edit Profile
                  </Link>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <MyCars />
    </Layout>
  );
}
export default Authorization(Profile);

Here is where profile can be edited. I made the previous profile as the current value, whenever the page is refresh the value will be lost.

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

import Layout from "@/components/Layout";
import Authorization from "@/HOC/Authorization";
import {
  useGetUserProfileQuery,
  useGetUserQuery,
  useUpdateUserNameMutation,
} from "@/store/ReduxStore/fetcherApi";
import { useState, useEffect } from "react";
import Image from "next/image";
import { FiEdit } from "react-icons/fi";
import PhoneInput from "react-phone-input-2";
import { useRouter } from "next/router";
import { usePostProfileMutation } from "@/store/ReduxStore/fetcherApi";
import Link from "next/link";

const ProfileSetup = () => {
  const router = useRouter();
  const [postProfile] = usePostProfileMutation();
  const [updateUserName] = useUpdateUserNameMutation();
  const { data: profile } = useGetUserProfileQuery();
  const { data: user } = useGetUserQuery();

  const [name, setName] = useState(user?.name);
  const [description, setDescription] = useState(profile?.description);
  const [businessStatus, setBusinessStatus] = useState(profile?.businessStatus);
  const [availability, setAvailability] = useState(profile?.availability);
  const [phoneNumber, setPhoneNumber] = useState(profile?.phoneNumber);

  const form = {
    description,
    businessStatus,
    availability,
    phoneNumber,
  };
  const submitProfile = async (e) => {
    e.preventDefault();
    updateUserName(name);
    postProfile(form);
    router.push("/profile");
  };

  return (
    <Layout>
      <form onSubmit={submitProfile}>
        <div className="bg-gray-100 ">
          <div className="profilesetupheader">
            <div className="profilesetupline">
              <div className="flex w-11/12 mx-auto xl:w-full xl:mx-4 items-center">
                <p className="setupheadertext">Profile Setup</p>
              </div>
            </div>
            <div className="mx-auto">
              <div className="xl:w-9/12 w-11/12 mx-auto xl:ml-8">
                <div className="rounded relative mt-8 h-48">
                  <div className="coverpicsone" />
                  <div className="coverpicstwo">
                    <p className="text-xs text-gray-100">Change Cover Photo</p>
                    <div className="ml-2 text-gray-100">
                      <FiEdit />
                    </div>
                  </div>
                  <input
                    className="backgroundprofile"
                    type="file"
                    name="myImage"
                    accept="image/png, image/gif, image/jpeg"
                    // onChange={profileImageBackgroundUpload}
                  />
                  <button className="profilepics">
                    <Image
                      src="/assets/images/d17.jpg"
                      alt="myprof"
                      className=" rounded-full"
                      layout="fill"
                    />
                    <div className="profilepicsoverlay" />
                    <div className="cursor-pointer flex flex-col justify-center items-center z-10 text-gray-100">
                      <FiEdit />
                      <p className="text-xs text-gray-100">Edit Picture</p>
                    </div>
                    <input
                      className="profileimage"
                      type="file"
                      name="myImage"
                      accept="image/png, image/gif, image/jpeg, image/jpg"
                    />
                  </button>
                </div>
                <div className="mt-16 flex flex-col xl:w-2/6 lg:w-1/2 md:w-1/2 w-full">
                  <label htmlFor="name" className="mylabel">
                    Name
                  </label>
                  <input
                    type="text"
                    name="name"
                    className="formname"
                    placeholder="John Doe"
                    onChange={(e) => setName(e.target.value)}
                    value={name}
                    required
                  />
                </div>
                <div className="mt-8 flex flex-col xl:w-3/5 lg:w-1/2 md:w-1/2 w-full">
                  <label htmlFor="description" className="mylabel">
                    Description
                  </label>
                  <textarea
                    type="text"
                    name="description"
                    className="formdescription"
                    placeholder="Let the world know who you are"
                    onChange={(e) => setDescription(e.target.value)}
                    value={description}
                    maxLength="400"
                    required
                  />
                </div>
              </div>
              <div className="ml-10">
                <div className="inline-flex justify-between py-4  space-x-20 ">
                  <div className=" flex flex-col xl:w-2/6 lg:w-1/2 md:w-1/2 w-full">
                    <label htmlFor="Buyer" className="mylabel">
                      Business Status
                    </label>
                    <select
                      name="businessStatus"
                      onChange={(e) => setBusinessStatus(e.target.value)}
                      value={businessStatus}
                      className="bg-gray-200 p-2"
                    >
                      <option>* Select Business Status</option>
                      <option value="buyer">Buyer</option>
                      <option value="seller">Seller</option>
                    </select>
                  </div>
                </div>
                <p className="mylabel">Available</p>
                <select
                  name="availability"
                  value={availability}
                  onChange={(e) => setAvailability(e.target.value)}
                  className="bg-gray-200 p-2 "
                >
                  <option>* Select Availability </option>
                  <option value="yes">Available</option>
                  <option value="no">Unavailable</option>
                </select>
                <div className="mt-6 mb-8 flex flex-col xl:w-2/6 lg:w-1/2 md:w-1/2 w-full pr-8">
                  <label htmlFor="phoneNumber" className="mylabel">
                    Phone Number
                  </label>
                  <PhoneInput
                    country={"us"}
                    name="phoneNumber"
                    onChange={phoneNumberChange}
                    value={phoneNumber}
                  />
                  <p className="w-full text-left text-xs pt-1 text-gray-500 ">
                    You might choose not to include your phone number if this
                    seems like a security concern.
                  </p>
                </div>
              </div>
            </div>
            <div className="ml-10 justify-end">
              <Link href="/profile" passHref>
                <button className="profilecancelbutton">Cancel</button>
              </Link>
              <button
                className="profilesubmitbutton"
                type="submit"
                onClick={submitProfile}
              >
                Save
              </button>
            </div>
          </div>
        </div>
      </form>
    </Layout>
  );
};

export default Authorization(ProfileSetup);

Here is my HOC component for redirecting users that are not authenticated.

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import axios from "axios";
import { useGetAuthQuery } from "@/store/ReduxStore/fetcherApi";
import { setHttpAgentOptions } from "next/dist/server/config";

export default (ChildComponent) => {
  const composeComponent = (props) => {
    const router = useRouter();

    const { data: authData } = useGetAuthQuery();
    const [page, setPage] = useState(undefined);

    useEffect(() => {
      if (authData && authData === false) {
        router.push("/login");
      } else {
        setPage(<ChildComponent {...props} />);
      }
    }, []);

    return <div>{page}</div>;
  };
  return composeComponent;
};

Specify size limit of the items going to be set in cache in nestjs In-memory cache

Is there any option to set the maxSize(in bytes) of the cache or the size limit for the items going to be stored in the in memory cache in nestjs .

My current implementation looks like :

//app module

CacheModule.register({
      max: 100,
      isGlobal: true
    })

// usage 

this.client.set(userId, inputId, { ttl: 600})

I checked the function signature and there were no options available .

How do I use data from an API using JSON parse

I am trying to get data by using JSON and use that data in a chart.
This is what i get from JSON

{ got json response {"id": 8900.937201864273, "jsonrpc": "2.0", "result": [{"__domain": [Array], "date:day": "07 Dec 2021", "date_count": 1, "unit_amount": 4}, {"__domain": [Array], "date:day": "08 Dec 2021", "date_count": 4, "unit_amount": 7.5}]} }

I need to put the exact dates i get as labels and unit_amount as data for the chart and I don’t know how to use parse.

const res = await countRecords();
const parseRes = JSON.parse(res);
console.log("res: ", parseRes)

If I try to console log parseRes.unit_amount I get the same result. Can anyone help me please. Thank you in advance.

Phaser 3: Show Interactable area

The game I’m creating doesn’t require any physics, however you are able to interact when hovering over/clicking on the sprite by using sprite.setInteractive({cursor: “pointer”});, sprite.on(‘pointermove’, function(activePointer) {…}); and similar.

I ran into some issues with the interactive area and wanted to debug it by showing the “area” that is interactable. However I could only find ways to do that that are related to Arcade Physics. Is there any way to get something like a debug outline around my interactable area without Physics?

Phaser 3: Change “Hitbox”/Interactive area of sprite without physics

The game I’m creating doesn’t require any physics, however you are able to interact when hovering over/clicking on the sprite by using sprite.setInteractive({cursor: "pointer"});, sprite.on('pointermove', function(activePointer) {...}); and similar. However I noticed two issues with that:

  1. The sprite has some area which are transparent. The interactive functions will still trigger when clicking on those transparent areas, which is unideal.

  2. When playing a sprite animation, the interactive area doesn’t seem to entirely (at all?) change, thus if the sprite ends on a frame bigger than the previous, there end up being small areas I can’t interact with.

One option I thought of was to create a polygon over my sprite, which covers the area I want to be interactive. However before I do that, I simply wanted to ask if there are simpler ways to fix these issues.

Responsive accessible navigation dropdown issue

I have a responive navigation which has a dropdown that cases me headaches.
Currenlty the navigatio has a event listener mouse over for desktop and on devices has a click event that adds a .is-active class.

For some reason the events aren’t working. I get this error. Uncaught ReferenceError: j is not defined.

I can’t figure it out. I leave the code below. hopefully you gus can help me out to find the issue.

const navBlocks = document.querySelectorAll(".nav-container");
const mediaQuery = window.matchMedia("(min-width: 900px)");
const navBp = "(min-width: 900px)";

let isMenuOpen = false;

for (var i = 0; i < navBlocks.length; i++) {
  const menu = navBlocks[i].querySelector(".sliding-nav .nav-wrap");
  const nav = navBlocks[i].querySelector(".sliding-nav");
  let btn = navBlocks[i].querySelector(".nav-cta");
  let navLinks = navBlocks[i].querySelectorAll(".sliding-nav .nav-items > li");
  //let isSubNavLink = navBlocks[i].querySelector(".has-nav-panel");

  btn.onclick = function (e) {
    e.preventDefault();
    isMenuOpen = !isMenuOpen;
    btn.setAttribute("aria-expanded", String(isMenuOpen));
    menu.hidden = !isMenuOpen;

    if (isMenuOpen) {
      nav.classList.add("is-open");
      document.body.classList.add("is-no-scroll", "is-fixed");
      //console.log(isMenuOpen);
    } else {
      nav.classList.remove("is-open");
      document.body.classList.remove("is-no-scroll", "is-fixed");
      //console.log(!isMenuOpen);
    }
  };

  Array.prototype.forEach.call(navLinks, function (el, i) {
    var currentNavLink = navLinks[i];

    currentNavLink.addEventListener("click", function () {
      megaNavClickAndTouchHandler(navLinks, currentNavLink);
    });

    currentNavLink.addEventListener("mouseover", function () {
      megaNavMouseOverHandler(navLinks, currentNavLink, navBp);
    });

    currentNavLink.addEventListener("mouseleave", function () {
      megaNavMouseLeaveHandler(navLinks, currentNavLink, navBp);
    });

    megaNavResetOnBreakPoint(navLinks, currentNavLink, mediaQuery);
  });

  function megaNavResetOnBreakPoint(elements, currentElement, mqNav) {
    if (matchMedia) {
      var navigationBar = currentElement.closest(".header");
      var navigationItems = currentElement.closest(".sliding-nav");

      mqNav.addListener(function () {
        if (mqNav.matches) {
          document.querySelectorAll("body")[0].classList.remove("is-no-scroll");
          navigationBar.classList.remove("is-active");
          navigationItems.classList.remove("is-active");
          navigationBar
            .querySelectorAll(".burger")[0]
            .classList.remove("is-active");
          megaNavClosePanels(elements);
        } else {
          megaNavClosePanels(elements);
        }
      });
    }
  }

  function megaNavClickAndTouchHandler(elements, currentElement) {
    var isSubNavLink = currentElement.classList.contains("has-nav-panel");
    var isSubNavLinkActive = currentElement.classList.contains("is-active");
    var navBarContainer = currentElement.closest(".header");

    if (!isSubNavLink) {
      window.location = currentElement.firstElementChild.getAttribute("href");
    } else if (isSubNavLink && !isSubNavLinkActive) {
      megaNavClosePanels(elements);
      currentElement.classList.add("is-active");
    } else {
      megaNavClosePanels(elements);
    }
  }
  function megaNavClosePanels(elements) {
    for (j = 0; j < elements.length; j++) {
      if (elements[j].classList.contains("has-nav-panel")) {
        elements[j].classList.remove("is-active");
      }
    }
  }
  function megaNavMouseOverHandler(elements, currentElement, breakPoint) {
    if (window.innerWidth >= breakPoint) {
      var isSubNavLink = currentElement.classList.contains("has-nav-panel");

      megaNavClosePanels(elements);
      currentElement.classList.add("is-active");
    }
  }

  function megaNavMouseLeaveHandler(elements, currentElement, breakPoint) {
    if (window.innerWidth >= breakPoint) {
      currentElement.classList.remove("is-active");
    }
  }

  function handleTabletChange(e) {
    // Check if the media query is true

    if (e.matches) {
      console.log("desktop");
      btn.setAttribute("aria-expanded", false);
      menu.removeAttribute("hidden");
      nav.classList.remove("is-open");
      document.body.classList.remove("is-no-scroll", "is-fixed");
    } else {
      console.log("mobile");
      btn.setAttribute("aria-expanded", false);
    }
  }

  // Register event listener
  mediaQuery.addListener(handleTabletChange);

  // Initial check
  handleTabletChange(mediaQuery);

  // TRAP TAB INSIDE NAV WHEN OPEN
  nav.addEventListener("keydown", (e) => {
    // abort if menu isn't open or modifier keys are pressed
    if (!isMenuOpen || e.ctrlKey || e.metaKey || e.altKey) {
      return;
    }

    // listen for tab press and move focus
    // if we're on either end of the navigation
    const menuLinks = menu.querySelectorAll(".nav-link");
    if (e.keyCode === 9) {
      if (e.shiftKey) {
        if (document.activeElement === menuLinks[0]) {
          menuToggle.focus();
          e.preventDefault();
        }
      } else if (document.activeElement === menuToggle) {
        menuLinks[0].focus();
        e.preventDefault();
      }
    }
  });
}

demo in codepen, please fork it to modify

Move y-Axis and hide in Chart.JS V3

So I’ve created this chart, and I’m trying to move the axis around so the Dark red is on the left, and the Blue and the sub of the bar charts is displayed, but I’m having trouble moving the dark red to the right side of this graf. I did try to use the position: 'right', but nothing changed.

I’m trying to make it look like this:

axis

But I can only get this:

var canvas = document.createElement('canvas');
    div = document.getElementById('container');
    canvas.id = "myChart";
    canvas.style.zIndex = 8;
    div.appendChild(canvas);
    const labels = [
        '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '1', '2', '3', '4', '5', '6', '7'
    ];

    const data = {
        labels: labels,
        datasets: [{
                label: 'Red',
                backgroundColor: 'rgb(255,0,0)',
                borderColor: 'rgb(255,0,0)',
                data: [3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8, 3, 2, 5, 2, 2, 5, 8],
                stack: 'combined',
                type: 'bar',
                order: 4
            },
            {
                label: 'Yellow',
                backgroundColor: 'rgb(255,255,0)',
                borderColor: 'rgb(255,255,0)',
                data: [0, 2, 2, 0, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                stack: 'combined',
                type: 'bar',
                order: 4
            },
            {
                label: 'Orange',
                backgroundColor: 'rgb(255,159,64)',
                borderColor: 'rgb(255,159,64)',
                data: [9, 21, 21, 0, 21, 21, 21, 21, 18, 18, 18, 18, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9],
                stack: 'combined',
                type: 'bar',
                order: 4
            },
            {
                label: 'Grey light',
                backgroundColor: 'rgb(224,224,224)',
                borderColor: 'rgb(224,224,224)',
                data: [9, 20, 20, 0, 20, 20, 21, 21, 19, 19, 19, 19, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9],
                stack: 'combined',
                type: 'bar',
                order: 4
            },
            {
                label: 'Blue',
                backgroundColor: 'rgb(30,144,255)',
                borderColor: 'rgb(30,144,255)',
                data: [328, 421, 421, 0, 421, 421, 422, 422, 344, 344, 344, 344, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328],
                stack: 'combined_first',
                yAxisID: 'Blue',
                order: 1
            },
            {
                label: 'Dark Red',
                backgroundColor: 'rgb(165,42,42)',
                borderColor: 'rgb(165,42,42)',
                data: [0.45, 1.55, 1.55, 0, 1.55, 1.55, 1.55, 1.55, 1.15, 1.15, 1.15, 1.15, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45],
                stack: 'combined_second',
                yAxisID: 'DarkR',
                order: 2
            },
            {
                label: 'Dark Grey',
                backgroundColor: 'rgb(80,80,80)',
                borderColor: 'rgb(80,80,80)',
                data: [18, 43, 43, 0, 43, 43, 44, 44, 38, 38, 38, 38, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18],
                stack: 'combined_third',
                yAxisID: 'GreyD',
                order: 3
            }
        ]
    };

    const config = {
        type: 'line',
        data: data,
        options: {
            plugins: {
                title: {
                    display: true,
                    text: 'WDC History Chart'
                },
                zoom: {
                    zoom: {
                        wheel: {
                            enabled: true,
                        },
                        pinch: {
                            enabled: true
                        },
                        drag: {
                            enabled: true
                        },
                        mode: 'x',
                    }
                }
            },

            scales: {
                y: {
                    stacked: true
                }
            }
        },
    };
    const myChart = new Chart(
        document.getElementById('myChart'),
        config
    );
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div id="container" class="wdc-canvas-size">
</div>

One of attribute lost data when assign javascript object

I spend a day for investigating this case, but seen no hope.

const Tests = (state = INIT_STATE, action) => {
switch (action.type) {
case GET_TEST_DETAIL:
return {
…state,
test: {},
error: {},
updatingTest: true,
}

    case GET_TEST_DETAIL_SUCCESS:
        const test = action.payload
        console.log(action.payload.shortName)//has data
        test["shortName2"] = action.payload.shortName//has data
        test["shortName"] = action.payload.shortName//empty string

        console.log(test)

        return {
            ...state,
            test: test,
            updatingTest: false,
        }

There is the picture captured when I console.log in firefox, and Edge:
enter image description here

How to use assets folder to load images with dynamic path in Nuxt?

I am using the latest Nuxt 2 version and I want to have my images cached and preload them before animation, static folder doesn’t allow me to cache images because this folder is not parsed by webpack, so for that documentation says that I should use assets folder and let webpack parse it for me, the problem is that everything works with static path for the images when I want to add src dynamically my whole path is copied over and it’s no longer using webpack for this.

This works:

<img class="lady" src="~/assets/lady/lady_001.png" />

Result: http://localhost:3000/_nuxt/assets/lady/lady_001.png

This not:

<img class="lady" :src="activeImage" alt="" />

Result: http://localhost:3000/~/assets/lady/lady_124.png

...
computed: {
    activeImage() {
      return `~/assets/lady/lady_${this.activeTimeline}.png`;
    },
  },

activeTimeline is just sequence of number from 000 to 180 converted to string. Is there any way to achieve this or I am forced to use some external library for caching static content?

JavaScript Date UTC datetime-local

I have a form where user can introduce date and time with input format datetime-local. When the form is summited a problem appears for the start-date “Value must 11:52 AM or earlier”, my local time is 13:52″. So i have to select -2 hours. How can I remove this problem. The form is limited for the start date to select only today and last 72 hours, same for end time.
The code is the following:

 <input type="datetime-local" name="start_timestamp" id="start_timestamp" required>
 <input type="datetime-local" name="end_timestamp" id="end_timestamp" required>

<script>
    //Do not let to select END-TIME and START TIME  in the PAST
    var today = new Date();
    var past = new Date(today.setDate(today.getDate() - 3)).toISOString().slice(0, 16);
    var today = new Date().toISOString().slice(0, 16);

    document.getElementsByName("start_timestamp")[0].min = past;
    document.getElementsByName("start_timestamp")[0].max = today;
</script>

<script>
    var today = new Date();
    var future = new Date(today.setDate(today.getDate() + 3)).toISOString().slice(0, 16);
    var today = new Date().toISOString().slice(0, 16);

    document.getElementsByName("end_timestamp")[0].min = today;
    document.getElementsByName("end_timestamp")[0].max = future;
</script>

I have an image also:

enter image description here

firestore query wait for nested foreach loop

I’m trying to populate an array with names from all documents in a collection, and also populate another array with all the subcollection documents from those parent documents.

  let data = []
  let names = []
  
  const suppliers = await db.collection('suppliers').get()
  
  suppliers.forEach(async supplier => {

    names.push({name: supplier.data().name, id: supplier.id })

    const deliveries = await db.collection('suppliers').doc(supplier.id).collection('deliveries').get()
    
    deliveries.forEach(delivery => {
      
      data.push(delivery.data())
    })
  })

  console.log(names) // Populated
  console.log(data) // Empty

The problem is that it doesn’t wait for the inner loop to finish before executing the code outside. The names array gets populated but the the data array is empty. How can i make the nested loop finish before executing the outside code?

How to pass a value between two different nodejs functions called by 2 different graphql mutations?

I’m trying to pass the data between two things. I will now explain it in detail. First graphql query calls a function func1() which is like

func1(){
  const a = await func2();
  return a;
}

func2(){
  return 7;
}

func3(value){
  return value
}

this func2 is returning an integer for example 7. For now I was using console input but now I want to get this result from another graphql mutation which calls a function func3(). I pass the required value for example 7 in the graphql mutation arguments which gets passed to function func3. How can I wait for this func3’s value in func1? Please help and if you want me to elaborate any specific thing, I’d be happy to do so.

Mocha async with await

According to this https://mochajs.org/#using-async-await when using await to test async function, there is no need to call done(). But with my code below it is complaining
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
I don’t want to use the hack to increase timeout.

describe('test', function () {
  it('upload all', async () => {
    const c = await setup();
    const files = await Test(c);
    expect(files.length).to.equal(3); 
  })
})

Any help is much appreciated