history push is pushing two times same key - javascript

English is not my language so there might be mistakes, i'm beginner programmer(react hooks), my form(antd) data is moving in url, everything is working fine except going back and changing form input value to another then going again forward, i can see there is now two times same key but different value, my point is now there is for example 'name=james' and 'name=susan', but i want to have just one 'name' and it should be the latest, should i be pushing differently? below is also a picture i made about this, if it helps to understand. when console.log(query); it shows both 'names'
Next page function comes from here :
< Form onFinish={nextPage}>
< / Form>
i'm going back from page b to page a like this:
const query = window.location.toString().split("?")[1];
const handleclick = () => {
history.push(`/pagea/${custId}?${query}`);
};
history push in nextPage function is like this
const query = window.location.toString().split("?")[1];
const nextPage = (order: rRequest) => {
history.push(`/customers/${custId}?${query}&name=${order.name}`);
};

const query = window.location.toString().split("?")[1];
var qry = "";
if (query) {
qry = query.split("&");
for (var i = 0; i < qry.length; i++) {
var curr = qry[i].split("=");
if (curr[0] == "name") {
qry.splice(i, 1);
i--;
}
}
qry = qry.join("&");
}
const nextPage = (order: rRequest) => {
history.push(`/customers/${custId}?${qry}&name=${order.name}`);
};

Related

Push all objects after a selected object into an array

I have a web page that returns a list of objects like:
date.pdf
names.csv
address.pdf
age.csv
cost.csv
budget.csv
data.pdf
race.pdf
contractors.csv
When a user checks budget.csv, I want every object with the .csv extension from that point to be pushed into csv_files[]. If they select names.csv, then every .csv including and after names is pushed into the array.
So the only data that gets pushed into the array is from the selected object downwards. How can I implement this?
Current code
const csv_files = []
$scope.listAllobjects = (err, data) => {
$.each(data.Contents, (index, value) => {
if (value.Key.endsWith("csv")) {
csv_files = [];
}
// Handle click on selection checkbox
$("#filesobjects-table tbody").on("click", 'input[type="checkbox"]', (e1) => {
const checkbox = e1.currentTarget;
const $row = $(checkbox).closest("tr");
const data = $tb.DataTable().row($row).data();
let index = -1;
// Prevent click event from propagating to parent
e1.stopPropagation();
// Find matching key in currently checked rows
index = $scope.view.keys_selected.findIndex((e2) => e2.Key === data.Key);
if (checkbox.checked && data.Key.endsWith("csv")) {
console.log(selected csv)
}
});
}
There's a few ways, I suppose, to approach this problem, but the most intuitive to me is this:
const csvList = ["date.pdf","names.csv","address.pdf","age.csv","cost.csv","budget.csv","data.pdf","race.pdf","contractors.csv"];
const selectedCsv = 'budget.csv';
function getCsvsAfter(csvList, selectedCsv) {
const filteredCsvs = [];
let found = false;
for (let csv of csvList) {
if (csv === selectedCsv) found = true;
if (found) filteredCsvs.push(csv);
}
return filteredCsvs;
}
console.log(getCsvsAfter(csvList, selectedCsv));
Iterate over every csv, and when you've hit the one you're trying to match, set a variable called found to true. Once it's true, you can add every following csv onto the list.
const list = ['date.pdf','names.csv','address.pdf','age.csv','cost.csv','budget.csv','data.pdf','race.pdf','contractors.csv'];
const selected = 'budget.csv'
const csv_files = list.slice(list.indexOf(selected))
console.log(csv_files)
Here you go with a pure JavaScript solution (Descriptive comments has been added in the below code snippet).
var contentData = ["date.pdf", "names.csv", "address.pdf", "age.csv", "cost.csv", "budget.csv", "data.pdf", "race.pdf", "contractors.csv"];
var myDiv = document.getElementById("cboxes");
for (var i = 0; i < contentData.length; i++) {
var checkBox = document.createElement("input");
var label = document.createElement("label");
checkBox.type = "checkbox";
checkBox.value = contentData[i];
myDiv.appendChild(checkBox);
myDiv.appendChild(label);
label.appendChild(document.createTextNode(contentData[i]));
}
// Event to handle the checkbox click
document.getElementById('getResult').addEventListener('click', () => {
document.getElementById('showResult').innerHTML = getCheckedValues();
});
function getCheckedValues() {
// filtered out the checked items.
const element = Array.from(document.querySelectorAll('input[type="checkbox"]'))
.filter((checkbox) => checkbox.checked).map((checkbox) => checkbox.value);
// element[0] will always return the first checked element and then we are getting index of that.
const checkedElemIndex = contentData.indexOf(element[0]);
// Slice the content data to get the elements from the checked element index.
return contentData.slice(checkedElemIndex, contentData.length)
}
<div id="cboxes"></div>
<button id="getResult">Get Result</button>
<pre id="showResult"></pre>

Looping through Json Arrays from API

I am currently trying to loop and add each element of the quantity of each bid and ask which appears as bids[0][1], bids[1][1], bids[1][2] and add each element in the Array sequence. Any help will be greatly appreciated.
I tried adding the array but I am unable to turn the Json data to code here. Below is the API reference
I tried the code:
const binanceTrade = JSON.parse(data)
const bidsQuantity = binanceTrade.bids[0][1]
const askQuantity = binanceTrade.asks[0][1]
for(var i = 0; i<bidsQuantity.length; i++){
var j = 1;
bidsQuantity = bidsQuantity.push(binanceTrade.bids[j][1])
console.log(bidsQuantity)
j++
//bids[0][1] + bids[1][2]
}
And the public Binance API route for reference: https://api.binance.com/api/v3/depth?symbol=BTCUSDT&limit=5
You can use reduce() to loop over the bids and asks arrays, totaling the second element of each item.
const binanceTrade = JSON.parse(data);
const bidsQuantity = binanceTrade.bids.reduce((acc, [_, quantity]) => acc + quantity, 0);
const asksQuantity = binanceTrade.asks.reduce((acc, [_, quantity]) => acc + quantity, 0);
One approach would be to use map
const bidsQuantity = [];
binanceTrade.bids.map((bids) => {
bidsQuantity.push(bids[1]);
});
You can do this again in a similar way for the asks

How to save Items in Local Storage with specific ID

I am practicing blog stuff. posting and deleting posts. mini social media I can say. And I wanted to save posts on localStorge. however I could save only 1 post at a time. and then I wanted to do it with IDs.
I create id with random number generator:
let newId = Math.floor(Math.random() * (1000000 - 100000) + 100000)
let postContents = {
ID : newId,
text: value,
}
an then I upload those values in let storedPosts = [] array.
then I save it to local storage with JSON:
let toJson = () => {
localStorage.setItem('storedPosts', JSON.stringify(storedPosts));
}
and then I get it from Local Storage:
let storedJsonPosts = localStorage.getItem('storedPosts')
let storedPosts_toUpload = JSON.parse(storedJsonPosts)
and then I join these two arrays together:
let storedPostsArray = storedPosts.concat(storedPosts_toUpload)
and after this I don't know what to do. I tried this:
let uploadStoredPosts = () => {
for (let i = 0; i < storedPostsArray.length; i++) {
let post = document.createElement('div')
$post_place.appendChild(post)
let text = document.createElement('p')
post.appendChild(text)
text.textContent = storedPostsArray[i].text
}
}
but it showed this:
It couldn't reach array values. plz help
Is this something that you're after?
The code reads from localStorage, parses that information, returns an empty array if it's the first time the user posted, pushes a new value to the array, stores that array by stringifying it, and the appending the new value to the document.
If you want the page to read from localStorage on page load, you need to add a function that reads from localStorage, and then loops through all posts to add each one of them by using appendToDocument().
StackOverflow doesn't allow the use of localStorage, so I used a variable for demo purposes.
I left out id as a property. You can play around with that by yourself, but I would suggest to use a timestamp as a foreign key ("id").
var justForDemoPurpose = null;
const addPostBtn = document.getElementById("add-button");
const addPostInput = document.getElementById("add-post");
const postContainerEl = document.getElementById("post-container");
addPostBtn.addEventListener('click', addPost);
function readFromLocalStorage(key) {
let localStorageItem = JSON.parse(justForDemoPurpose);
// let localStorageItem = JSON.parse(localStorage.getItem(key));
console.log('returning items:', localStorageItem);
return localStorageItem;
}
function storeInLocalStorage(key, value) {
justForDemoPurpose = JSON.stringify(value);
// JSON.stringify(localStorage.setItem(key, value));
}
function addPost() {
let postValue = addPostInput.value;
if (postValue) {
const LOCAL_STORAGE_KEY = 'posts';
let storedPosts = readFromLocalStorage(LOCAL_STORAGE_KEY) || [];
storedPosts.push(postValue);
storeInLocalStorage(LOCAL_STORAGE_KEY, storedPosts);
appendToDocument(postValue);
}
}
function appendToDocument(postValue) {
let divEl = document.createElement('div')
divEl.textContent = postValue;
postContainerEl.appendChild(divEl);
}
<div class="addPostContainer">
<input id="add-post" placeholder="Type here"> <button id="add-button">Add Post</button>
</div>
<section id="post-container"></section>

Pre-fill form with local storage

I'm loading questions from a JSON into my EJS template and want to populate each field from localStorage. The following saves the last value of each dropdown, text, and slider element:
var select = document.getElementsByTagName('select');
for (var i = 0; i < select.length; i++){
select[i].value = localStorage.getItem(i);
}
jQuery("select").change(function () {
for (var i = 0; i < select.length; i++){
localStorage.setItem(i, select[i].value);
}
});
I repeat this for all "input" tags. The issue is that the select values also get passed into text and slider — and vice versa (i.e. if I enter values for text and slider, they overwrite the select values, except they are left blank).
My end goal is to save each form-fields' most recent value so that my entries are not lost when I refresh the page.
It would be a lot more elegant to create a single localStorage entry representing your saved values, rather than pollute LS with many entries for each field. I would recommend something like this:
function save() {
const selects = document.querySelectorAll('select');
// select other element types
// ...
const selectValues = [...selects].map(select => select.value);
const textValues = [...textInputs].map(textInput => textInput.value);
const sliderValues = [...sliderInputs].map(sliderInput => sliderInput.value);
const savedObj = { selectValues, textValues, sliderValues };
localStorage.savedFormValues = JSON.stringify(savedObj);
}
That way, you only create a single entry in localStorage, and each entry type is quite distinct. Then, to get the values, just do the same thing in reverse:
function populate() {
const selects = document.querySelectorAll('select');
// ...
const { selectValues, textValues, sliderValues } = JSON.parse(localStorage.savedFormValues);
selectValues.forEach((selectValue, i) => selects[i].value = selectValue);
// ...

Keep Javascript constant the same after function is recalled

I am trying to create a dynamic list so when the user performs a search it will repopulate the list. The problem is that I can't seem to make an immutable constant to store the original div content. Every time the function get's called this variable gets reinitialized.
Is there a way to achieve this without using cookies ? Any help is sincerely appreciated. The code is not complete because I couldn't get passed this step but if you think I am totally heading toward the wrong direction please let me know.
const originalList = document.getElementById('patientList').getElementsByTagName('li');
frozen = Object.freeze(originalList);
<script>
const originalList = document.getElementById('patientList').getElementsByTagName('li');
frozen = Object.freeze(originalList);
var newList = '';
var found = false;
function filterPatients(){
var searchQuery = document.getElementById('search');
var query = searchQuery.value;
var listContainer = document.getElementById('patientList');
var patientList = listContainer.getElementsByTagName('li');
for (var i = 0; i < originalList.length; i++){
var link = patientList[i].getElementsByTagName('a');
var link = link[0].text;
/** remove whitespaces for easy comparison **/
link = link.toLowerCase();
query = query.toLowerCase();
link = link.replace(/\s/g, "");
query = query.replace(/\s/g, "");
/** check every character in query **/
if (link.length > query.length && link.substring(0,query.length) == query){
found = true;
newList += '<li>' + patientList[i].innerHTML + '</li>';
}
}
if (found == true){
listContainer.innerHTML = newList;
newList = '';
}
else{
listContainer.innerHTML = "<li>No patient by that name</li>";
}
console.log(frozen);
}
</script>
const originalList = document.getElementById('patientList').getElementsByTagName('li').cloneNode(true);
Make originalList a copy of the element. Currently, you are setting originalList and patientList to be the same list of elements, so changing one will also change the other. Use element.cloneNode(true) to make a deep copy of a DOM element

Categories