I wanna create a logout function that should reset all the counters. Therefore, I need to access the countervariables from another module (and set them to the original value). How can I do that within javascript and react?
Here is my import declaration and the logoutUser function from the AuthState.js file:
import chatState from "../Chat/ChatState";
const logoutUser = () => {
console.log(questioncounter);
chatState.questioncounter = 2;
chatState.questioncounter_event = 1;
chatState.currentNode = 1;
dispatch({
type: LOGOUT_USER,
});
};
And here are the local variables from ChatState.js:
let questioncounter = 2;
let questioncounter_event = 1;
let currentNode = 1;
Related
I will try to be brief and to the point. In our school we use Google Sheets as a class book. I have a script that counts the absences of individual students. The script is written in Google Apps Scripts (GAS), but the purpose of the application and even GAS are irrelevant to this question.
I'm currently trying to rewrite my old code and try to implement Jest unit testing. So my question will be simple. How can I mock a global variable that I call inside the function under test?
Here I paste the part of the code that introduces the global variables:
const absenceFileId = "some_string"
const teachersFileId = "some_string"
const studentGroupsId = "some_string"
const classbookFolderId = "some_string"
// STATE
let teachers = {}
let groups = {}
let subjectCounter = {}
let errors = []
let students = {}
function setupStateVariables() {
teachers = getTeachers(removeEmptyRowsAndHeader(getValuesArray(teachersFileId, 0, 1, 1, 50, 3)));
groups = getGroups(removeEmptyRowsAndHeader(getValuesArray(studentGroupsId, 0, 1, 1, 400, 6)))
subjectCounter = createSubjectCounter(removeEmptyRowsAndHeader(getValuesArray(studentGroupsId, 1, 1, 1, 200, 4)))
}
Subsequently, I need to update the global variable subjectCounter inside the function:
function updateSubjectCounter(group, schoolClass, subject) {
if (!(subject in subjectCounter[schoolClass])) {
return
}
if (group) {
subjectCounter[schoolClass][subject][group] += 1
} else {
let keys = Object.keys(subjectCounter[schoolClass][subject])
if (keys.length > 1) {
for (let key of keys) {
subjectCounter[schoolClass][subject][key] += 1
}
} else {
subjectCounter[schoolClass][subject][null] += 1
}
}
}
I have the previous code in the main.js module.
I export the function for testing as follows. If statement is here due to GAS enviroment.:
if (typeof module !== 'undefined') {
module.exports = {
"getTeachers": getTeachers,
"getGroups": getGroups,
"createSubjectCounter": createSubjectCounter,
"updateSubjectCounter": updateSubjectCounter
}
}
For testing, I use the main.test.js module, which looks like this:
const main = require('./main');
test("Test funkce updateSubjectCounter", () => {
main.updateSubjectCounter("", "a", "IFM")
expect(subjectCounter).toEqual({something})
The question is how to mock the global variable subjectCounter in this test?
EDIT: I am using local enviroment with NodeJS for testing.
I am trying to store value in the global variable then pass it through Axios, but I can't store it in the variable. here is my code sample.
const voteSubmit = document.querySelector('#voteSubmit');
const votevalue = document.querySelectorAll('.votting_buttons button');
let voteNum;
votevalue.forEach((btn) => {
btn.addEventListener('click', () => {
voteNum = btn.dataset.votno;
});
});
how could I store it?
I am coming from vue and used to composable functions. I am trying to figure out the way to do this in svelte
So I make a js file and import store and then was trying to make a function that I could call on multiple components and act individually
swipe.js file
import { writable, derived, get } from 'svelte/store';
function createSwipe() {
const dyFromStart = writable(0)
function moveEvent(eventType, val){
console.log('moveEvent', eventType, val, get(dyFromStart))
dyFromStart.update(n => n + 1);
}
const dxScore = derived(dyFromStart, $dyFromStart => $dyFromStart + 3)
const dyScore = derived(dyFromStart, $dyFromStart => Math.round($dyFromStart + 100));
return {
moveEvent,
dxScore,
dyScore,
};
}
export const swipe = createSwipe();
then in .svelte component import function in script and decompose into subparts
<script>
import { swipe } from "$lib/swipe";
let { moveEvent, dxScore, dyScore } = swipe
</script>
<p>{$dxScore}{$dyScore}</p>
<button on:click="() => moveEvent">button</button>
Well eventually I want to turn into a swipe component hence name but trying to get fundamentals down. So I want to be able to have unique store for each component and for this if I use multiple of this .svelte component the state is shared amongst all.
And not just like three idk modal.svelte components I want to use swipe for a bunch of diff components maybe a photoViewer.svelte right just generic swipe function and use same code for all.
or would I just have to keep the state like const dyFromStart = writable(0) be just let dyFromStart = 0 in each .svelte component and pass it into a pure js function that returns results and update local .svelte variables
Adding this as the non store more pure js things I was trying but couldn't get to be reactive so accepting the answer below on store method that worked and sounds like is the correct approach
export function createSwipe() {
let dyFromStart = 0
function moveEvent(eventType, val){
console.log('moveEvent', eventType, val, dyFromStart, dxScore(), dyScore())
dyFromStart++
}
function dxScore(){ return dyFromStart + 3 }
// const dzScore = derived(dyFromStart, $dyFromStart => $dyFromStart + 3)
const dyScore = () => Math.round(dyFromStart + 100)
return {
moveEvent,
dxScore,
dyScore,
dyFromStart
};
export function createSwipe() {
let dyFromStart = 0
let dxScore = dyFromStart + 3
let dyScore = Math.round(dyFromStart + 100)
function moveEvent(eventType, val){
console.log('moveEvent', eventType, val, dyFromStart, dxScore, dyScore)
dyFromStart++
dxScore = dyFromStart + 3
dyScore = Math.round(dyFromStart + 100)
}
return {
moveEvent,
dxScore,
dyScore,
dyFromStart
};
I suppose that works fine just not reactive with $ and need to call to update a diff local var if doing that
this would seem most sveltey to me or something like it as far as composable function type style not store type
export function createSwipe() {
let dyFromStart = 0
function moveEvent(eventType, val){
console.log('moveEvent', eventType, val)
dyFromStart++
}
$: dxScore = dyFromStart + 3
$: dyScore = Math.round($dyFromStart + 100)
return {
moveEvent,
dxScore,
dyScore,
};
}
I don't understand the question fully, so I try to reiterate first what I think you want:
You want to use your swipe function in multiple places
Each usage of that swipe function should be independent of all others
If that's correct, then the answer is simple: Don't do export const swipe = createSwipe(). Delete that part and instead export the create function to use directly within your components. That way you create a new independent instance each time:
<script>
import { createSwipe } from "$lib/swipe";
let { moveEvent, dxScore, dyScore } = createSwipe()
</script>
<p>{$dxScore}{$dyScore}</p>
<button on:click="() => moveEvent">button</button>
I am trying to generate a unique id number for each React component, this id will be assigned to the component when it is mounted.
I am using the code below, the function callOnce takes a function and ensure that the function is only executed once per component.
import React, { useRef } from "react";
// Helper function that makes fn execute only once
const callOnce = (fn) => {
let called = false;
let result;
return (...params) => {
if (called) return result;
called = true;
result = fn(...params);
return result;
};
};
let lastId = 0;
const getId = () => {
console.log("incrementing");
lastId = lastId + 1;
return lastId;
};
export default function App() {
const { current: getIdOnce } = useRef(callOnce(getId));
const id = getIdOnce();
return <div>{id}</div>;
}
When I execute this code, the id that is displayed is 2, but logically it should be 1.
The getId function is only called once (the message incrementing is printed once), so there is no other way that the variable lastId is incremented again.
Why is the value 2 ?
codesandbox link
I not know what the problem, but the fix can be that:
import React, { useRef } from "react";
// Helper function that makes fn execute only once
const callOnce = (fn) => {
let called = false;
let result;
return (...params) => {
if (called) return result;
called = true;
result = fn(...params);
return result;
};
};
let lastId = 0;
const getId = () => lastId++;
export default function App() {
const { current: getIdOnce } = useRef(callOnce(getId));
const id = getIdOnce();
return <div>{id}</div>;
}
If I found the problem reason, I will update my comment ☺
I found the answer in another thread. Basically when using React with React.StrictMode wrapper, some functions are executed twice.
The reason the id is 2 is because the function getId is executed twice
Link of the answer with more details
I wonder if this
const getData = () => {
const data = 1; // simplified complicated operations
return data;
};
export default getData();
is any performance difference than this:
const getData = () => {
const data = 1;
return data;
};
const toexport = getData(); // cache to a variable before exporting
export default toexport;
The question boils down to how export actually works. I read many articles and I can manage to make it work, but I haven't understood what it does under the hood (couldn't find an article about my question).
What if an export is imported from difference import, will the getData() be called once or being called for each import?
function getData() {
console.log('getData');
return 1;
}
// will `export default getData();` be like this
const importSomeWhere = getData();
const importSomeWhereElse = getData();
// or this?
const exportCached = getData();
const importSomeWhere2 = exportCached;
const importSomeWhereElse2 = exportCached;
It will be evaluated only once. Here's example from What Happens When a Module Is Imported Twice?
In increment.js, we declare a variable called counter
let counter = 0;
counter++;
export default counter;
In consumer.js we import 2 times, but the counter is evaluated once for the first import
import counter1 from './increment';
import counter2 from './increment';
counter1; // => 1
counter2; // => 1