JQuery onclick parameter passing with append - javascript

Im currently trying to append a variable amount of text to a list. Each item would need to be clickable with their own value being passed to a function. I cannot seem to get this to work and keep getting a 'Object' is not defined at HTMLAnchorElement.onclick error, where object is the name of the object in the list. Here is the code that I am using for this:
if (user) {
id = user.uid;
ref = firestore.collection("Users").doc(id);
console.log(user);
console.log(ref.get());
ref.get().then(function(doc){
nameString = doc.data().name;
console.log(nameString);
const outputHeader = document.querySelector("#headMain");
const outputInfo = document.querySelector("#genInfo");
outputHeader.innerText = "Welcome " + nameString;
outputInfo.innerText = "Create a class or choose a class from the left";
});
firestore.collection("Users").doc(id).collection("Classrooms").get().then(function(querySnapshot){
querySnapshot.forEach(function(doc){
classNameString = doc.id;
console.log(doc.id, " => ", doc.data());
$("li").append(''+doc.id+'<br/>');
});
});
}
The current testInfo function is as follows:
function testInfo(val){
console.log(val);
}

The following html code cannot work
'+doc.id+'
You are missing the double quotes, so the onclick is executed on the anchor element (the "#")
What you want to do is:
'+doc.id+'

Related

Javascript returning multiple checkbox values

I'm having some trouble trying to get multiple checkbox values. It currently is working, just not in the way I wanted/was hoping it would. Right now anything checked is appended to the bottom of the body and not inline with the function it was aiming to be inserted into.
I'm trying to avoid using JQuery or anything except JavaScript as it's all we've currently covered in our class.
function favMedia(media){
var media = document.forms['mediapref']['media'].value;
return media;
}
function pets(pet){
var pet = document.getElementsByName('pets')
for (var checkbox of pet){
if (checkbox.checked)
document.body.append(checkbox.value + ' ');
}
}
function about(text){
var info = document.forms['personal']['about'].value;
return info;
}
function infoForm(media, pet, text){
document.getElementById('infoset').innerHTML = favMedia(media) + "<br>" + pets(pet) + "<br>" + about(text);
}
Is there some way I can assign it just to a single variable to return and then throw into the last function?
Also please give me any tips or improvements on any aspect of the functions if you have any.
Put it in a string that you return from the function.
function pets(pet) {
var pet = document.querySelector('[name="pets":checked');
let selected = [...pet].map(p => p.value);
return selected.join(', ');
}

Firebase - Get field using variable as property

Im trying to get a field from a "doc.data" using a variable, the thing is that i want to reuse that function with different field names.
This is the code:
btnsEditvalue.forEach((btn) => {
btn.addEventListener("click", async (e) => {
try {
propToEdit = e.target.dataset.prop;
const doc = await getElement(e.target.dataset.id, col);
const element = doc.data();
console.log(element.propToEdit)
editElement.value = element.e.target.dataset.prop;
id = doc.id;
}
catch {
console.log("error");
}
});
});
The output is undefined, because "propToEdit" isnt a field in my database.
You can try passing the dynamic key using the bracket notation, instead of the dot notation.
Refer to javascript object property accessors.
const element = doc.data()
const ELEMENT_KEY: string = 'propToEdit'
console.log(element[ELEMENT_KEY])
You can access fields dynamically with a custom name
fieldName = "stringValue"
element[fieldName]
this does depend entirely on where doc from doc.data() is maintained
You can wrap it into a function as well, this will return the value or null.
You can swap null out with any other default value you want.
function getField(fieldName, doc){
return doc.data()[fieldName] || null;
}

name.forEach is not a function after button is clicked

I am trying to edit/update current data using the contenteditable attribute which I have successfully enabled onclick. My 'enter' key allows the data to be submitted. However, the console.log reads that a PUT request has been made for a particular list item but without the 'title' or 'isbn' being updated along with it.
Another prominent issue is that my console.log shows books.forEach is not a function, and I have no idea why this is the case since the code inside that function is processed.
HTML ('li' items are solely JS-Generated with a POST request)
<div id="divShowBooks">
<li id="[object HTMLParagraphElement]">
<p id="24" name="anID" placeholder="24">1</p>
<p id="TEST" name="aTitle" placeholder="TEST">TEST</p>
<p id="12345" name="anISBN" placeholder="12345" contenteditable="true">12345</p>
<button>Delete</button>
</li>
</div>
JavaScript
var book_list = document.querySelector('#divShowBooks');
book_list.innerHTML = "";
var books = JSON.parse(this.response);
books.forEach(function (book) {
// Text information to be displayed per item
var id = document.createElement('p');
id.type = 'text';
id.innerHTML = book.id;
var title = document.createElement('p');
title.type = 'text';
title.innerHTML = book.title;
var isbn = document.createElement('p');
isbn.type = 'text';
isbn.innerHTML = book.isbn;
// Defining the element that will be created as a list item
var book_item = document.createElement('li');
// Displays id, title and ISBN of the books from the database
book_item.appendChild(id);
book_item.appendChild(title);
book_item.appendChild(isbn);
// Creates an ID attribute per list item
book_item.setAttribute("id", id)
// Assigns attributes to p items within book items
id.setAttribute("id", book.id)
title.setAttribute("id", book.title)
isbn.setAttribute("id", book.isbn)
// Adding a generic name to these elements
id.setAttribute("name", "anID")
title.setAttribute("name", "aTitle")
isbn.setAttribute("name", "anISBN")
title.addEventListener('click', function (e) {
e.preventDefault();
title.contentEditable = "true";
title.setAttribute("contenteditable", true);
title.addEventListener('keypress', function (e) {
if (e.keyCode === 13) {
e.preventDefault();
xhttp.open("PUT", books_url + '/' + book.id, true);
var editTitle = new FormData() /
editTitle.append("title", document.getElementsByName("aTitle")[0].value)
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
xhttp.send(); //
}
});
});
UPDATE
I have added the following to my code. This seems to display my database items as an array in the log. But, I am now having a similar issue with Uncaught TypeError: JSON.parse(...).map is not a function:
var params = [
id = 'id',
title = 'title',
isbn = 'isbn',
createdAt = 'createdAt',
updatedAt = 'updatedAt'
];
var books = JSON.parse(this.response).map(function(obj) {
return params.map(function(key) {
return obj[key];
});
});
console.log(books);
UPDATE 2
Here is an image of what I receive in the console.log. The first part displays the original JSON content and the second is my attempt to convert each object into an array.
See Image
You have to make sure that your books variable actually contains an Array after parsing.
Alternatively, but this wouldn't make sense, just to address the "books.forEach is not a function" issue, You can use Object.assign([], this.response);. To make sure that books will contain an array, you wrap it in a try catch and make something like this:
var books = [];
try {
books = Object.assign([], this.response);
} catch (error) {
books = [];
}
books.forEach will then be expected to always work but you have to be careful because something like this could happen:
var myStringObject = "{'myProperty':'value'}";
var myArray = Object.assign([], myStringObject );
//myArray value is ["{", "'", "myProperty", "'", ":", "'", "value", "'", "}"]
Which will leave you having to check the book in your forEach callback if it is correct:
//at the topmost of your forEach callback
if(!book.id) throw BreakException; //A simple break will not work on forEach
This will leave you again with another exception to handle. Or leave you having to use the traditional for loop since you cannot short circuit Array.forEach with a break.
TLDR: make sure books always contains an Array.
You are getting books from JSON.parse(), which means books is an object and not an array.
forEach is an array method.
Try console logging books and look for an array inside of it.

updating a multidimensional array stored in session storage

I have taken over a project and am not totally familiar with JQuery and session storage. The issue is that after updating the info and clicking update it provides an error, "Uncaught SyntaxError: Unexpected token u in JSON at position 0
at JSON.parse (<anonymous>)
at fillArray (main.js? [sm]:313)
at UpdateProduct (main.js? [sm]:234)
at HTMLButtonElement.onclick ((index):405)".
Included link to github repo:https://github.com/bveasey/Jquery-project
function UpdateProduct() // called on click of an update btn
{
// capture id from hidden element set in editproduct function
var productId = $('#txtHiddenId').val();
console.log("***** line:233 *****\n product id =" + productId);
fillArray(productId);
console.log("***** line:235 *****\n Fill array called!");
BindTable();
console.log("***** line:237 *****\n Bind Table called!");
}
// other functions
function fillArray(prodid)
{
console.log("***** line:310 *****\n Begin Fill Array");
// find the item in the product array and update it
$.each(JSON.parse(sessionStorage.setItem('products',
JSON.stringify(productArray))), function (idx, v)
{
console.log("***** line:315 *****\n " + product.id);
// Check if current prodid is the id wanted
if (product.id === prodid)
{// ids match
console.log("***** line:319 *****\n product is's match");
// populate data
product.id = productId;
product.arrivalDate = $('#modalRequestedArrivalDate').val();
product.productCode = $('#modalProductCode').val();
product.description = $('#modalDescription').val();
product.quantity = $('#modalQuantity').val();
product.quantityType = $('#modalQuantityType').val();
product.plant = $('#modalPlant').val();
product.shippingMethod = $('#modalShippingMethod').val();
product.specialInstructions = $('#modalSpecialInstructions').val();
console.log("***** line:310 *****\n END Fill Array");
}
});
}
// bind table just updates the table.
Storage#setItem() returns void, you can't parse void using JSON.parse(), void is not valid JSON syntax.
The Error tells you exactly where the problematic code is,
$.each(JSON.parse(sessionStorage.setItem('products', JSON.stringify(productArray))), function (idx, v)...
The sessionStorage.setItem() here doesn't return anything that the JSON.parse() can parse.

how do I catch firebase search error?

I have a function that takes user's input and search through firebase database. What I want to do is catch the any error most especially when their is no match for the user input I want to display as something like "No match was found for the number entered".
this is the function I'm using
function searchNSN(data){
var container = document.getElementById('searchresult');
container.innerHTML = '';
var FindNSN = document.getElementById('searchinput').value;
firebase.auth().onAuthStateChanged((user) => {
if (user) {
var BusinessesId = firebase.auth().currentUser.uid;
return database.ref('/Businesses/' + BusinessesId + '/Inventory/' + FindNSN).once('value').then(function(snapshot) {
var Results = snapshot.val();
var Productkey = Object.keys(snapshot.val())[0];
var ResultCard = `
<h1 class="searchtitle first">${Results.ProductName}</h1>
<p class="searchtext">${Results.ProductDescription}<span class="class">${Results.NSN}</span></p>
<p class="showproductdetail" onclick="SHOWSEARCHDETAIL();"><a href> Show Product Details </a href></p>
`
container.innerHTML += ResultCard;
});
}
})
}
I know the console logs the error but how do I implement catching the error and reporting it to the user?
If the database location/reference does not contain any data, it will still trigger a value event but with an empty DataSnapshot (i.e. snapshot.val() is null). You may check if snapshot.val() === null, and if it does, let the user know that there are no results.
Reference, the value event section.

Categories

Resources