Angular Cannot read property of null - javascript

In a web app I have two box containing some elements. I also have an aside with filters (composed by a selection). At the beginning the filters are all selected, and it works. But when I try a combination which find nothing in the first list but there are some data in the second list, I got an error. This is the when I call the Service in the controller:
if(data){ // If i have some response form serve
var tmp = null;
var lastName = null;
angular.forEach(data.people, function(ppl){
if(ppl.lastName != lastName){
if (lastName != null){
$scope.people.push(tmp);
}
// Clean the tmp
tmp = {
name : null,
count : 0,
products : []
};
// Update lastName
lastName = ppl.lastName;
}
// Add the actual row in the ob
tmp.name = lastName;
tmp.count += ppl.personCount;
tmp.products.push(ppl);
});
// Process lasts elements (if there are some) in the array
if(tmp.products.length > 0){
$scope.people.push(tmp);
}
The error is: Cannot read property 'products' of null
I've tried to write: var tmp = []; instead of null, but it says Cannot read property 'products' of undefined

I think the angular.forEach is giving you a scoping issue. Try the below code instead.
if(data && data.people.length > 0){ // If i have some response form serve
var tmp = {};
var lastName = null;
for(var i = 0; i < data.people.length; i++){
if(ppl.lastName != lastName){
if (lastName != null){
$scope.people.push(tmp);
}
// Clean the tmp
tmp = {
name : null,
count : 0,
products : []
};
// Update lastName
lastName = ppl.lastName;
}
// Add the actual row in the ob
tmp.name = lastName;
tmp.count += ppl.personCount;
tmp.products.push(ppl);
};
// Process lasts elements (if there are some) in the array
if (tmp && tmp.products && tmp.products.length > 0)
$scope.people.push(tmp);
}
}

Related

I want to take input from the user as object and push it to array that i already created in local storage

I'm having an issue with creating the array in the first place I couldn't push (person) to the array. I changed my code several times because of this error and I tried to define the array inside and outside the function but nothing changed.
the error
testreg.php:53 Uncaught TypeError: Cannot read properties of null (reading 'push')
Thanks for the help.
var feedback = document.getElementById("feedback");
var userArray = JSON.parse(localStorage.getItem("key"));
var person = {
name: document.getElementById("nameinput").value,
email: document.getElementById("emailinput").value,
passowrd: document.getElementById("passwordinput").value };
function checkemail(userArray, email) {
var i;
var userArray = JSON.parse(localStorage.getItem("key"));
let isFound = false;
if(userArray != undefined)
for (i = 0; i < userArray.length; i++) {
let oldemail = userArray[i].email;
let newemail = document.getElementById("emailinput").value;
if (newemail === oldemail) { isFound = true; i = userArray.length;
return feedback.innerHTML = "email exist please log in or register with different email";
}}
if(!isFound) {
return storeName(person, userArray);
}}
function storeName(person, userArray){
var person = {
name: document.getElementById("nameinput").value,
email: document.getElementById("emailinput").value,
passowrd: document.getElementById("passwordinput").value };
var userArray = JSON.parse(localStorage.getItem("key"));
userArray.push(person);
userArray = JSON.stringify(userArray)
localStorage.setItem("key", userArray);
console.log(userArray);
}
function clearStorage(){
localStorage.clear();
}

JSON.Stringify returns empty array when Stringifying array of objects

I have an array which is initialized with
var detail = [];
// Have also tried var detail = new Array;
Through the rest of my code, I loop through a data set creating an object in the following manner
while(true) {
var tempObj = {
qty : "",
size : "",
adr : "",
dir : ""
}
// Some Logic
tempObj.qty = val;
tempObj.size = val;
tempObj.adr = val;
tempObj.dir = val;
detail.push(tempObj);
}
Then when I attempt to JSON.Stringify my detail array to send through an AJAX request, it returns a blank array []. This can also be seen in the below screenshot of the console.
Note: The indent at the bottom calling out the prototype as an object is because the screenshot is from the object I am attempting to send to my server. There is other non array based data in that object. I want to stringify the array so it properly sends to the server.
What is causing this behavior and how can I correct it?
Edit 1: Execution of JSON.stringify(detail)
var requestObj = {
field1: “a”,
field2: “b”,
field3: “c”,
data: JSON.stringify(detail)
}
Edit 2: Add full block of code
$("#submit-button").click(function() {
var reqDate = $("#reqDate").val();
var wonum = $("#wonum").val();
var svc = $("#svc").val();
var complaint = $("#complaint").val();
var comments = $("#comm").val();
var detail = new Array;
var topValid = false;
$(".tb-rw").each(function() {
var qty = $(this).find(".quantity");
var size = $(this).find(".size");
var adr = $(this).find(".address");
var dir = $(this).find(".direction");
var mgk = $(this).find(".mgKey");
var tempObj = {};
if(fail == true || topValid == true) {
alert("Please Make Sure all Inputs are Filled Out");
return;
} else {
//tempArr.push(qty.val(), size.val(), dir.val());
tempObj.qty = qty.val();
tempObj.size = size.val();
tempObj.dir = dir.val();
}
findSimilarJobs(adr.val(), mgk.val(), function(data) {
if(data != "clear") {
console.log("FAILED VALIDATION");
console.log(data);
adr.css('border-color', 'red');
alert("Please Make Sure all Addresses are Valid");
return;
} else {
//tempArr.push(adr.val());
tempObj.adr = adr.val();
}
detail.push(tempObj);
});
});
console.log("Preparing to send!");
var requestData = {
"requestedDate": reqDate,
"svc": svc,
"wonum": wonum,
"complaint": complaint,
"comment": comments,
"data": JSON.stringify(detail)
};
console.log(requestData);
console.log(JSON.stringify(detail));
});
Stringify should be all lower case like this stringify, otherwise is won't work. So like, this JSON.Stringify(detail) should be this JSON.stringify(detail)
your tempObj is JSON object and it should have key:value like below
while(true) {
var tempObj = {
qty : "",
size : "",
adr : "",
dir : ""
}
// or you can create empty object
// var tempObj = {};
tempObj.qty = val;
tempObj.size = val;
tempObj.adr = val;
tempObj.dir = val;
detail.push(tempObj);
}

sheetjs excel to json - adding extra <tr> for each row

I couldn't find anything on SO that matched my question. I'm using Sheetjs plugin to convert an excel sheet into json, and displaying it using jquery in the browser. I'm able to do the conversion and display, but I have a use-case where I need to validate each of the json rows with data returned from a jquery ajax 'GET' call.
I'm able to perform that validation as well. Once each excel json row is validated against the values from the ajax response, based on a set of rules, the excel json row is marked either a success row or an error row. For success rows, I perform no action. For error row, I need to add an additional key/value pair in the json element, denoting the error type, and the error description. Further, this error row, when displayed in the browser needs to have a css style with a color:red for red text, to indicate an error.
I haven't seen anything in Sheetjs documentation that might allow me to do this, but I'm pretty sure it can be done. In the code below, I have to modify the helper function called BindTable() in order to add the css style to set the text color to red IF it is an error row. I also have to somehow add a for each of the error rows in order to display the error type and error description.
In the below code, I need to be able to display the invalidRequests JSON object with the css style applied to display the text in red color. Or, if there is a way to directly manipulate the exceljson JSON object to somehow append the key/value pairs of MSG1/message to each of the error rows, that would be even better. I realize that due to the nature of this question, I can't create a jsfiddle, but any ideas/suggestion/comments would be extremely helpful, even if it doesn't provide the complete solution.
Expected format:
author1 JOHN DOE USA N.AMERICA
ERROR: THIS AUTHOR NAME ALREADY EXISTS IN THE SYSTEM!
This is the code that I currently have:
//Excel Reader
function ExcelToTable(event) {
event.preventDefault();
var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.xlsx|.xls)$/;
/*Checks whether the file is a valid excel file*/
if (regex.test($("#excelfile").val().toLowerCase())) {
var xlsxflag = false; /*Flag for checking whether excel is .xls
format or .xlsx format*/
if ($("#excelfile").val().toLowerCase().indexOf(".xlsx") > 0) {
xlsxflag = true;
}
/*Checks whether the browser supports HTML5*/
if (typeof (FileReader) != "undefined") {
var reader = new FileReader();
reader.onload = function (e) {
var data = e.target.result;
//pre-process data
var binary = "";
var bytes = new Uint8Array(data);
var length = bytes.byteLength;
for(var i=0;i<length;i++){
binary += String.fromCharCode(bytes[i]);
}
// /pre-process data
/*Converts the excel data in to object*/
if (xlsxflag) {
// var workbook = XLSX.read(data, { type: 'binary' });
var workbook = XLSX.read(binary, {type: 'binary'});
}
else {
var workbook = XLS.read(binary, { type: 'binary' });
}
/*Gets all the sheetnames of excel in to a variable*/
var sheet_name_list = workbook.SheetNames;
// console.log('Sheet name list : ' + sheet_name_list);
var cnt = 0; /*This is used for restricting the script to
consider only first sheet of excel*/
// sheet_name_list.forEach(function (y) { /*Iterate through
all sheets*/
/*Convert the cell value to Json*/
if (xlsxflag) {
exceljson =
XLSX.utils.sheet_to_json(workbook.Sheets['CUSTOM_EXCEL_TAB'],{defval:
"NULL"});
var emptyAuthorCells =[];
var invalidCountryCells = [];
Object.keys(exceljson).forEach(function(value, key) {
if(exceljson[key].AUTHOR == 'ADD'){
}
else if(exceljson[key].AUTHOR == 'NULL'){
emptyAuthorCells.push({'MARKET':
exceljson[key].MARKET, 'REGION':exceljson[key].REGION,
'PARTNER':exceljson[key].PARTNER, 'AUTHOR': exceljson[key].AUTHOR });
}
//check effective end date
if((exceljson[key].DATE_ENDING != '') ||
(exceljson[key].DATE_ENDING <= getTodayDate())){
invalidCountryCells.push({
'MARKET': exceljson[key].MARKET,
'REGION':exceljson[key].REGION, 'PARTNER':exceljson[key].PARTNER, 'AUTHOR':
exceljson[key].AUTHOR
});
}
});
var emptyActionCellsMessage = "There were " +
emptyAuthorCells.length + " rows with Author=Null <br />";
var completedActionCellsMessage = " Success! There
were " + emptyAuthorCells.length + " rows with authro=Null <br />";
var invalidDateMsg = "There are missing or incorrect
date values.";
var validCompareDataMessage = "Success! All data has been successfully validated!";
var invalidCompareDataMessage = "Validation Failed!
Data does not match Rules.";
}
else {
var exceljson =
XLS.utils.sheet_to_row_object_array(workbook.Sheets[y]);
}
var conflictRows = [];
var returnedRows = [];
var errorReturnedRows = [];
if(emptyAuthorCells.length == 0){
var uniqueAuthor = $.unique(exceljson.map(function
(d){
return d.MARKET;
}));
var doAllValidations = function(){
var ajaxList = [];
var ajxIndex = 1;
$.each(uniqueAuthor, function (index, value){
var jqResponse =
$.ajax({
type: "get",
url: "authorlist.cfm?method=getlist&name=" +
value,
dataType: "json"
});
ajaxList.push(jqResponse);
jqResponse.then(
function( apiResponse ){
$.each (apiResponse, function (cc) {
if(apiResponse[cc].hasOwnProperty('SUCCESS')){
errorReturnedRows.push({
'success':
apiResponse[cc].SUCCESS,
'message':
apiResponse[cc].MESSAGE,
'country_code' : value
});
}
else{
returnedRows.push(apiResponse[cc]);
}
// }
// }
});
}
);
});
return ajaxList;
};
// /LOOP OVER country_code
}
var invalidRequests = [];
var validRequests = [];
$(function() {
var ajaxCalls = doAllValidations();
//begin apply
$.when.apply($, ajaxCalls).done(function(){
//console.log(ajaxList);
$('#hidReturnedRows').val();
$('#hidReturnedRows').val(JSON.stringify(returnedRows));
if (exceljson.length > 0 && cnt == 0) {
if((emptyAuthorCells.length != 0) ||
(errorReturnedRows.length!=0) ) {
//data is invalid
console.log("data is invalid");
$('#displayErrors tr
td.previewSuccessClass').html("");
$('#displayErrors tr
td.previewErrorsClass').html(emptyActionCellsMessage);
$('#export-file').addClass('hidebtn');
}
else{
//outer loop
var found = false;
var book_found = false;
var response_validation_errors = [];
var message = "The author's zone is
incorrect";
var message2 = "This book already
exists";
$.each(exceljson, function(x, ej){
// console.log("inside outer
loop");
found = false;
$.each(returnedRows, function(y,
rr){
//compare inner row with outer
row to make sure they're the same
if(rr.AUTHOR_ID == ej.ID &&
rr.AUTHOR_NAME == ej.NAME)
{
if((rr.AUTHOR ==
ej.NATIVE_AUTHOR) && (rr.BOOK_QUALITY == ej.AUTHOR_ZONE)){
// console.log("found!");
found = true;
}
}
});
if(found){
invalidRequests.push({
"AUTHOR": ej.NAME,
"AUTHOR_ZONE":
ej.AUTHOR_ZONE,
"COUNTRY": ej.COUNTRY
});
}
else{
validRequests.push(ej);
}
});
// /outer loop
}
BindTable(exceljson, '#exceltable');
cnt++;
}
})();
//end apply
});
};
if (xlsxflag) {/*If excel file is .xlsx extension than creates a
Array Buffer from excel*/
reader.readAsArrayBuffer($("#excelfile")[0].files[0]);
}
else {
reader.readAsBinaryString($("#excelfile")[0].files[0]);
}
}
else {
alert("Sorry! Your browser does not support HTML5!");
}
}
else {
alert("Please upload a valid Excel file!");
}
}
//Helper funcs
function BindTable(jsondata, tableid, invalidreqs) {/*Function used to convert the JSON
array to Html Table*/
var columns = BindTableHeader(jsondata, tableid); /*Gets all the column
headings of Excel*/
//ADDED .map() & .find() INSTEAD OF NESTED LOOPS
jsondata.map(a => {
// SEARCH FOR AN ELEMENT IN invalidreqs THAT MATCH THE
// CRITERIA TESTED FOR IN THE FUNCTION
if (invalidreqs.find(b => {
return a.AUTHOR == b.AUTHOR && a.BOOKNAME == b.BOOKNAME && a.COUNTRY ==
b.COUNTRY;
})) {
a.MSG = "THIS ROW ALREADY EXISTS";
}
});
console.log (jsondata);
//THE BELOW CODE NEEDS TO BE CHANGED
var row$ = $('<tr/>');
for (var colIndex = 0; colIndex < columns.length; colIndex++) {
var cellValue = jsondata[i][columns[colIndex]];
row$.append($('<td/>').html(cellValue));
}
//console.log("before table append");
$(tableid).append(row$);
if( has_error ){
row$.addClass( 'response-errors' );//add class to make text red
var error_row = $('<tr/>');
var error_cell = $('<td/>');
error_cell.attr('colspan', column.length); //set cols to span lenght of row
error_cell.html("SET ERROR MESSAGE TO DISPLAY BASED ON invalidreq object");
error_row.append( error_cell );
$( tableid ).append( error_row );
}
}
// /Outer loop
}
function BindTableHeader(jsondata, tableid) {/*Function used to get all
column names from JSON and bind the html table header*/
var columnSet = [];
var headerTr$ = $('<tr/>');
for (var i = 0; i < jsondata.length; i++) {
var rowHash = jsondata[i];
for (var key in rowHash) {
if (rowHash.hasOwnProperty(key)) {
if ($.inArray(key, columnSet) == -1) {/*Adding each unique
column names to a variable array*/
columnSet.push(key);
// console.log(key);
headerTr$.append($('<th/>').html(key));
}
}
}
}
$(tableid).append(headerTr$);
return columnSet;
}
Ok so what you want to do is:
1) Assign the row index to the invalidRequests object, on line 191 like this:
invalidRequests.push({
"AUTHOR": ej.NAME,
"AUTHOR_ZONE": ej.AUTHOR_ZONE,
"COUNTRY": ej.COUNTRY,
"index": x,
"MSG1": "Put the error message here"
});
Now it is very easy to determine which row has an error.
Since the invalidRequests is a private object of the ExcelTable function, you will need to
2) pass it on to the BindTable function like this:
BindTable(exceljson, '#exceltable', invalidRequests);
3) modify the BindTable function to check for invalidRequests and handle them:
function BindTable(jsondata, tableid, invalidreqs) {
var columns = BindTableHeader(jsondata, tableid);
for (var i = 0; i < jsondata.length; i++) {
//look for rows with error
var has_error = false
var invalidreq
for(var u=0;u<invalidreqs.length;u++){
if(i==invalidreqs[u].index){
//found invalid request belonging to current row, set flag
has_error = true
invalidreq = invalidreqs[u] // and store the current invalidrequest infos on temp obj
//break - not really needed
}
}
var row$ = $('<tr/>');
for (var colIndex = 0; colIndex < columns.length; colIndex++) {
var cellValue = jsondata[i][columns[colIndex]];
row$.append($('<td/>').html(cellValue));
}
$(tableid).append(row$);
if(has_error){
row$.addClass('error') // add css class which will make the text red or whatever
var error_row = $('<tr/>') // create error row
var error_cell = $('<td/>')
error_cell.attr('colspan',columns.length) // set column to span over all columns of table
error_cell.html(invalidreq.MSG1)
error_row.append(error_cell)
$(tableid).append(error_row);
}
}
}
Please note it is not clear, nor specified in your code, in which column the error should appear. Try to implement that yourself by pushing that info into the invalidRequests object and reading it out on BindTable.

Extract a value that passed the truth test in a Parse Array

Issue
i saved an array of 2 users in parse , i want to extract in the array only the one who pass the truth test , only the one who is not equal to the current value of parse.User. this is what i'm doing
Array.find(function(e){
return e.id != Parse.User.current().id
})
Doing this return me an undefined value
this is how i'm saving the array
function createRooms(){
var chatRooms = new ChatRooms();
var userOne = Parse.User.current()
var userTwo = AchatsDetailsData.value.seller
var chateur = [userOne, userTwo]
chatRooms.set("lastMessages", "undefined");
chatRooms.set("Users", chateur);
chatRooms.save().then(function(results){
console.log("created")
goToChatDetails()
}, function(error){
})
}
this is how i'm loading the data.
function loadrooms(){
var roomsQuery = new Parse.Query("ChatRooms")
roomsQuery.equalTo("Users", Parse.User.current())
roomsQuery.notEqualTo("lastMessages", "undefined")
roomsQuery.descending("updatedAt")
roomsQuery.find().then(function(results){
roomsAll.refreshAll(results,
function(oldItem, newItem){
return oldItem.id == newItem.id;
},
function(oldItem, newItem){
oldItem.time == newItem.get("updatedAt");
},
function(newItem){
return new Rooms(newItem.id, newItem.get("lastMessages"), newItem.get("Users"), newItem.get("updatedAt"), newItem)
}
)
})
}
function Rooms(id, lastmessage, user, time, parsObject){
var self = this;
this.id = id;
this.lastmessage = lastmessage;
this.user = user.find(function(e){
return e.id != Parse.User.current().id
})
this.RigID = this.user.get("RigID");
this.time = time;
this.userName = this.user.get("nom") + " " + this.user.get("prenom")
this.parsObject = parsObject;
this.userpicture = this.user.get("photo");
this.pics = Observable(function(){
if(this.userpicture == null){
return "http://az664292.vo.msecnd.net/files/B2MmOFAy2wjpUo71-model-045.jpg"
}else{
return this.userpicture
}
})
}
so i have 2 users in the array chateur when i click to createRooms function, i want to extract the user who is not equal to the current user for displaying my chat room
This code works perfectly , i just forget to include my Users array into the query
roomsQuery.include("Users")

If I don't fill all the first email (of 3) the action doesn't execute

I have this script to send automatically the load information by email:
if(confirm('', 'Are you sure?') == true) {
// enviar mails
var emails = new Array();
if (getFormFieldValue('4469') != '') {
emails[0] = getFormFieldValue('4469');
}
if (getFormFieldValue('4470') != '') {
emails[1] = getFormFieldValue('4470');
}
if (getFormFieldValue('4471') != '') {
emails[2] = getFormFieldValue('4471');
}
var msgBody = 'blablabla' ;
var s = new SendMessage();
if(emails.length > 0) {
s.sendEmailMessage(emails, msgBody);
}
confirmForm();
}
As you can see, there are 3 mails, if I don't fill the first one, nothing happen, if i complete only the second or the thirst email also nothing. The only way to executed this script is filling the first email.
How can i fix this?
Thank you
Try using an array index variable to keep track of which entry in the email array you are populating. You want to always start with index 0, then 1, etc. regardless of which emails are filled in:
var emails == new Array();
var emailIndex = 0;
if (getFormFieldValue('4469') != '') {
emails[emailIndex ++] = getFormFieldValue('4469');
}
if (getFormFieldValue('4470') != '') {
emails[emailIndex ++] = getFormFieldValue('4470');
}
if (getFormFieldValue('4471') != '') {
emails[emailIndex ++] = getFormFieldValue('4471');
}
// emails should be populated now starting from index 0
If the form field values are always incremental from 4469-4471, you can also simplify and shorten your code with a for loop:
var emails = new Array();
var emailIndex = 0;
for (var fld = 4469; fld <= 4471; fld++)
if (getFormFieldValue(fld.toString()) != '')
emails[emailsIndex++] = getFormFieldValue(fld.toString());
EDIT: As noted by #Naren, this can be made even simpler by using Array.push:
var emails = new Array();
for (var fld = 4469; fld <= 4471; fld++)
if (getFormFieldValue(fld.toString()) != '')
emails.push(getFormFieldValue(fld.toString()));
Just use Array.push(), like this:
var x = getFormFieldValue(y);
if (x != '') emails.push(x);
This can be easily used iteratively: you can for example create an array with the field values to read from and loop over it.

Categories

Resources