How to update childSnapShot value in firebase web - javascript

I have two products on my product table in firebase. Here it is:
Now I want to update product_quantity when the user takes action. But when the user chooses two or more products and inputs the quantity of chosen products, only the last product quantity got replaced or updated. product selection view looks like this:
And 2nd product selection looks like this:
Here is the code for javascript:
firebase.auth().onAuthStateChanged((user) => {
if (user) {
var uid = user.uid;
for (var i = 0; i < itemCnt; i++) {
var uidValueInv = $(".item-wrapper").eq(i).find(".uidVal").val();
var productNameInv = $(".item-wrapper").eq(i).find(".productName").val();
var amountInv = parseFloat($(".item-wrapper").eq(i).find(".amount").val());
var sellingPriceInv = parseFloat($(".item-wrapper").eq(i).find(".sellPrice").val());
var buyingPriceInv = parseFloat($(".item-wrapper").eq(i).find(".buyPrice").val());
var quantityInv = parseFloat($(".item-wrapper").eq(i).find(".quantity").val()) || 0;
var quantityCount = amountInv - quantityInv;
console.log(quantityCount)
var query = firebase.database().ref("Products/").child(uid).
orderByChild("uid").equalTo(uidValueInv);
query.once("child_added", function(snapshot) {
snapshot.ref.update({
product_quantity: quantityCount.toString()
})
})
}
})
I uploaded here only firebase code, not the entire javascript how product_quantity and other stuff calculate, because those things work perfectly I checked the console that got the product_quantity perfectly. I think I just need to change in firebase update code.

I change below code:
firebase.database().ref('Products/').child(uid).once('value').then(function (snapshot)
{
for (var i = 0; i < itemCnt; i++) {
var uidValueInv = $(".item-wrapper").eq(i).find(".uidVal").val();
console.log(uidValueInv);
var amountInv = parseFloat($(".item-wrapper").eq(i).find(".amount").val());
var quantityInv = parseFloat($(".item-wrapper").eq(i).find(".quantity")
.val()) || 0;
var quantityCount = amountInv - quantityInv;
console.log(quantityCount)
snapshot.forEach(function (childSnapshot) {
var uid_value = childSnapshot.child('uid').val();
console.log(uid_value)
if (uid_value === uidValueInv) {
childSnapshot.ref.update({
product_quantity: quantityCount.toString()
});
}
})
}
})

Related

sum up user input with javascript

I'm trying to store a user input in a variable and output it.
I actually thought it would be very easy, but right now I'm stuck on this task
I'm trying to store this in an array. but I would also be happy if it was simply stored in a variable and I could output it.
I've been searching for it for a long time, but I have the feeling that I don't know exactly what to look for
here is my code:
let inputValuePrice = document.getElementById("myInput2").value;
let outputSumme = document.getElementById("summe");
outputSumme = parseFloat(inputValuePrice);
let sum = [];
sum.push(outputSumme);
console.log(sum);
<input type="number" id="myInput2" />
<input type="text" id="summe" />
edit:
I'm sorry. I'll explain it again in more detail. I want to add the number after each entry. It is a kind of to-do list with products and prices. each product is entered one by one along with the price. I would then like to add up the price of each product. In this case it is enough for me if it is first output in the console. If it is correct then I will let it output to the html.
if you need to calculate the sum of all inputs values as an integer or a float number it's very simple. you can use a simple function to sums all of your array elements like this:
let inputValuePrice = document.getElementById("myInput2").value;
let outputSumme = document.getElementById("summe");
outputSumme = parseFloat(inputValuePrice);
let sum = [];
sum.push(outputSumme);
console.log(getSumOfArray(sum));
function getSumOfArray(array){
let sumOfElements=0;
for (let i=0;i<array.length;i++){
sumOfElements=sumOfElements+array[i];
}
return sumOfElements;
}
If your array elements are all numbers you can use the reduce operator as follows:
const sumOfArray = sum.reduce((a, b) => a + b, 0)
Unfortunately I don't understand how it works. I have now the products with prices in the indexedDB in my code. There I wanted to read them out and sum them up again in an array. I'll send you the whole code. I would be very grateful for an explanation. what is wrong with my thinking? Here is my code.
This snippet is in a function that when run puts the products in a list in the HTML. The products are created in a foreach loop and in that I intercept the prices and send them outside of the function to another function which then has the data to calculate with. I hope it is understandable. I'll link the whole code at the end of this thread.
let products = makeTransaction('produkte', "readonly");
let request = products.getAll();
request.addEventListener('success', (event) => {
event.preventDefault();
document.querySelector('#product-list').innerHTML = "";
let data = event.target.result;
data.forEach((element) => {
/*-----------Elemente Kreieren------------*/
let li = document.createElement("li");
let edit = document.createElement('i');
let spanPrimary = document.createElement('span');
let inputLabel = document.createElement('label');
let productName = document.createElement('span');
let productPrice = document.createElement('span');
let spanSecondary = document.createElement('span');
let checkBox = document.createElement('input');
let closeBtn = document.createElement("span");
/*-----------Elemente einfügen------------*/
li.setAttribute('data-key', element.id);
productName.appendChild(document.createTextNode(element.title));
productPrice.appendChild(document.createTextNode(element.price + " €"));
spanPrimary.appendChild(productName);
spanPrimary.appendChild(productPrice);
inputLabel.appendChild(checkBox);
spanSecondary.appendChild(inputLabel);
li.appendChild(edit);
li.appendChild(spanPrimary);
li.appendChild(spanSecondary);
li.appendChild(closeBtn);
/*-----------Elemente klassifizieren------------*/
li.className = "mdl-list__item mdl-shadow--2dp";
edit.className = "material-symbols-outlined icon-edit-document";
edit.textContent = 'edit_document';
spanPrimary.className = "mdl-list__item-primary-content";
spanSecondary.className = "mdl-list__item-secondary-action";
inputLabel.className = "mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect";
productName.className = 'product-text';
productPrice.className = 'product-preis';
checkBox.className = "mdl-checkbox__input";
checkBox.setAttribute('id', 'my-id');
checkBox.setAttribute('type', 'checkbox');
closeBtn.className = "material-symbols-outlined hiding-list-item";
closeBtn.textContent = 'close';
componentHandler.upgradeElement(li);
let list = document.getElementById("product-list").appendChild(li);
// Füge die "edit" Funtion hinzu
let editieren = document.getElementsByClassName("icon-edit-document");
for (let i = 0; i < editieren.length; i++) {
editieren[i].onclick = function() {
showProducts(element.id);
}
}
// Füge die "close" Button Funktion hinzu
let close = document.getElementsByClassName("hiding-list-item");
for (let i = 0; i < close.length; i++) {
close[i].onclick = function() {
deleteProduct();
}
}
// Function for totalizing product prices
let produktPreis = element.price
sumPrice(produktPreis);
});
});
request.addEventListener('error', (event) => {
console.log(event.target.error);
});
}
and now the summation...
function sumPrice(produktPreis) {
produktPreis = parseFloat(produktPreis);
let arr = [];
arr.push(produktPreis);
console.log(getSum(arr));
console.log(sumOfArray);
function getSum(array) {
let sumOfElements = 0;
for (let i = 0; i < arr.length; i++) {
sumOfElements = sumOfElements + array[i];
}
return sumOfElements;
}
}
I've always been able to help myself. But I can't get any further with this supposedly simple thing.
and for the completeness. Here is my temporarily hosted website and Github. Thanks also for the previous replies.
Project site
https://liquefied-stripe.000webhostapp.com/
Github
https://github.com/StevoEs/Einkaufsliste/blob/main/main.js
Thanks!

Firebase + JQuery infinite scrolling

I managed to successfully call a function whenever a page is scrolled to its maximum, but I don't know how to make that function call the data from the database and them in the correct order. Here is my current code:
function loadMoreData(num) {
var rawDataRef = db.ref("chat/"+group);
rawDataRef.on("value", function(data) {
if (data.hasChildren() == true) {
var uid = firebase.auth().currentUser.uid;
var keys = Object.keys(data.val());
var startAt = keys[num-1];
var dataRef = db.ref("chat/"+group+"/").startAt(startAt).limitToLast(15);
dataRef.on("value", function(snapshot) {
var data = snapshot.val();
var keys = Object.keys(data);
for (var i = 0; i < keys.length; i++) {
var k = keys[i];
if (data[k].uid == uid) {
$("#data").prepend('<div class="dataByMe">'+data[k].data+'</div><br><br>');
} else if (data[k].uid != uid) {
$("#data").prepend('<div class="dataByOthers">'+data[k].data+'</div><br><br>');
}
}
});
}
});
}
My code shows the last 25 data when the page is first loaded, and then, when the page is scrolled to the top, I need to load 15 more data before the point where the last 25 data starts, and show them in the order of latest data at the bottom. How exactly do I do this?
Note: The dataByMe and dataByOthers classes are because I need to style them differently.

localStorage is not updating edited information

I have problem editing local storage data. I saved Array of Array-list in local storage and it works, or save. However, when i tried to edit, it only edit temporarily and the edited data disappear when i refresh the page and it shows the original data i saved
function editinfo(){
var name = document.getElementById("nameB").value;
var price = document.getElementById("priceB").value;
var quant = document.getElementById("quantityB").value;
var retrieved = window.localStorage.getItem("done");
var pro = JSON.parse(retrieved);
for (i = 0; i < pro.length; ++i){
if(pro[i][0] === name){
pro[i][1]= price
pro[i][2] = quant;
} else{
console.log("There is no such data to edit");
}
}
window.localStorage.setItem("done", JSON.stringify(pro));
}
// I saved information on local storage, I read data from server.
var bevInventory = $.getJSON('http://pub.jamaica-inn.net/fpdb/api.php?username=jorass&password=jorass&action=inventory_get');
function Info(){
var info = [];
bevInventory.done(function(result){
for(i = 0; i < result.payload.length; ++i){
if(result.payload[i].namn != ""){
var makeList = [result.payload[i].namn, result.payload[i].price, result.payload[i].count];
info.push(makeList);
}
}
var xx = window.localStorage.setItem("done", JSON.stringify(info));
})
return info;
}
One solution is to check first, and add data to local storage if it does not exist. Like this
function editinfo() {
var name = 'bob';
var price = 1;
var quant = 2; // loaded dynamically from page.
if (window.localStorage.hasOwnProperty("done")) {
var retrieved = window.localStorage.getItem("done");
var pro = JSON.parse(retrieved);
for(i = 0; i < pro.length; ++i){
if(pro[i][0] === name){
pro[i][1] = price
pro[i][2] = quant;
}
}
} else {
pro = [[name, price, quant]];
}
window.localStorage.setItem("done", JSON.stringify(pro));
}
Your code fails if there is no "done" data initially in localStorage. JSON.parse() parses null (because of no data) and then error occurs on line
pro.length
So it's better to check if it's a first launch and there is no data:
if (!pro) {
pro = [];
}
Example here
After first executing of editinfo() data successfully saves in localStorage.

Cordova/Phonegap - Stock an array when I close the app (use them when I re-open)

I am using an array in my app. Something like that
[{pseudo: "test", id: 0}, {pseudo: "Lucia", id: 2}]
I'd like to keep this array even when I close the app, how is it possible to do it ?
Moreover I'd like to use them directly when I open the app (not when it is in background)
UPDATE:
I tried with this,
stockage :
var ami = ({
idx: id
});
var ami_json = JSON.stringify(ami);
sessionStorage.setItem("ami", ami_json);
lecture only launched the first time I open the app (I put it just after my controller started) but I got null value in console.log
var amiStorage = [];
var storageAmisNotifies = window.localStorage;
var ami_json = sessionStorage.getItem("ami");
var ami = JSON.parse(ami_json);
console.log(angular.toJson(ami));
console.log(ami);
amiStorage.push(ami);
console.log(amiStorage);
console.log(angular.toJson(amiStorage));
UPDATE 2 :
$scope.isChecked is for ng-class, I'd like to take the id of my json but it is like [[{"pseudo": pseudo, "id": id}]] ...
amisNotifies[i].id doesn't work
var amisNotifies = [];
$scope.isChecked = [];
var storageAmisNotifies = window.localStorage;
var ami_json = window.localStorage.getItem("info");
var ami = JSON.parse(ami_json);
if (ami != null){
amisNotifies.push(ami);
if (amisNotifies.length > 0) {
for (var i = 0; i < amisNotifies.length; i++) {
console.log(amisNotifies[[i]].id);
$scope.isChecked[amisNotifies[i].id] = "fa fa-check-circle-o pull-right";
}
}
}
Try using localStorage instead of sessionStorage
var ami = ({
idx: id
});
var ami_json = JSON.stringify(ami);
window.localStorage.setItem("ami", ami_json);
And also here
var amiStorage = [];
var storageAmisNotifies = window.localStorage;
var ami_json = window.localStorage.getItem("ami");
var ami = JSON.parse(ami_json);
console.log(angular.toJson(ami));
console.log(ami);
amiStorage.push(ami);
console.log(amiStorage);
console.log(angular.toJson(amiStorage));

How to prevent angular to render page until all data will be present?

I have following issue:
I trying to "merge" data from two collections from MongoDB.
Everything looks OK until I try to show some data from second query that came exactly after first one:
$scope.getData = function() {
var pipeline, fromDateRangeStatement, toDateRangeStatement, service, joblist;
service = ($scope.service && $scope.service.value) ? $scope.service.value : {
$exists: true
};
pipeline = $scope.utils.getSessionUsersPipeline($scope.fromDate, $scope.toDate,
$scope.checkedResults, $scope.checkedStatuses, service, $stateParams, $scope.usersLimit);
toApi.post("/users/aggregate", {
pipeline: pipeline
}).success(function(data) {
$scope.users = data.data.result;
for (var i = 0; i < $scope.users.length; i++) {
var path = "/jobs/" + scope.users[i].id + "/sessions";
var user = $scope.users[i]
toApi.get(path).success(function(data) {
user.error = data.data.records[0].exception // this is not shows up in HTML!
console.log(data.data.records[0].exception); // but it can be logged!
})
}
})
};
So, problem is: $scope.users are rendered at my page, while their attribute error is not. Looks like data became rendered before I change attributes for every user in for loop.
How this can be handled?
Thanks
Below are two different solutions
Each of your GET requests is async, so you need to wait for all of them to resolve. You could wrap each request in its own Promise and collect all Promises like so
var promises = [];
for (var i = 0; i < $scope.users.length; i++) {
promises[i] = new Promise(function (resolve, reject) {
var path = "/jobs/" + scope.users[i].id + "/sessions";
var user = $scope.users[i]
toApi.get(path).success(function(data){
user.error = data.data.records[0].exception;
console.log(data.data.records[0].exception);
resolve(user);
})
}
Then use Promise.all() to group all promises together as one Promise and wait for it to resolve.
Promise.all(promises).then(function(users) {
$scope.users = users;
});
Quick example: http://codepen.io/C14L/pen/QNmQoN
Though, a simpler and better solution would be to display the users one after one, as their API calls return
for (var i = 0; i < $scope.users.length; i++) {
var path = "/jobs/" + $scope.users[i].id + "/sessions";
toApi.get(path).success(function (data) {
$scope.users[i].error = data.data.records[0].exception;
$scope.users[i].done = true;
console.log(data.data.records[0].exception);
});
}
Simply add into your template a check for $scope.users[i].done = true and ony show that dataset with ng-show="user.done".
var user = $scope.users[i] only assign the value of $scope.users[i]. so later when you do user.error=..., it is not going to change the $scope. try this:
for (var i = 0; i < $scope.jobs.length; i++) {
var path = "/jobs/" + scope.users[i].id + "/sessions";
toApi.get(path).success(function(data){
$scope.users[i].error = data.data.records[0].exception // this is not shows up in HTML!
console.log(data.data.records[0].exception); // but it can be logged!
})
}
2 elements about handling this :
If you use {{value}} replace this by
<span ng-bind="value"></span>
So you won't see brackets.
Now you want to wait for all your request before changing anything in order to not have partial data displayed. This is easy too :
var promiseArray = [];
for (var i = 0; i < $scope.users.length; i++) {
var path = "/jobs/" + scope.users[i].id + "/sessions";
var user = $scope.users[i]
promiseArray.push(toApi.get(path)).success(function(data){
var result = {i:i, data:data};
return result
});
}
$q.all(promiseArray).then(function success(result){
for(var i=0; i < promiseArray.length;i++){
$scope.users[result.i].error = result.data.data.records[0].exception;
}
});
Bascially i'm waiting for all request to be resvoled before changing any data so this will run in the same angular loop. So the DOM will be only refreshed once and the user won't see any partial results.

Categories

Resources