for loop randomly crashing on certain iterations - javascript

there must be someone out there who can spot my error! I'm parsing an xml feed and running through a loop to get certain items on the page:
www.highlandradio.com/feed/
I am encountering an error on the line where I am setting the variable mp3Test. All I want to do is to set it equal to the url attribute of the enclosure tag (if it exists). This is why I am including the test to check if each item has an enclosure tag, if it does I am setting it to be equal to the url tag but if it doesn't I am setting it to be equal to 'null.mp3' for now. When running through the loop I am getting the correct numbers for a certain amount and then on some iterations of the loop, i crashes. I am using titanium and so am not getting any proper error messages. It simply highlights the line where I set up mp3Test and says to debug the current instruction pointer. I'm going crazy with this. Please help.
var url="http://www.highlandradio.com/feed/";
var xhr = Titanium.Network.createHTTPClient();
xhr.onload = function() {
// Data is returned from the blog, start parsing
var doc = this.responseXML.documentElement;
// begin looping through blog posts
var items = doc.getElementsByTagName("item");
var enclosure = doc.getElementsByTagName("enclosure");
console.log("NEWEST Enclosure Length -----------"+enclosure.length);
for (var i = 0; i < items.length; i++) {
var itemsEnclosureLength=items.item(i).getElementsByTagName("enclosure").length;
var itemsEnclosureExists=items.item(i).getElementsByTagName("enclosure");
console.log("EXISTs ----------------------------------"+ itemsEnclosureExists);
console.log("Newest ENCLOSURE LENGTH ---------------------- [ "+i+ " ]" + itemsEnclosureLength);
var str=items.item(i).getElementsByTagName("content:encoded").item(0).text;
console.log("STRING TEST "+ str);
var patt1=/([a-z\-_0-9\/\:\.]*\.(jpg|jpeg|png|gif))/i;
var urlMatch = str.match(patt1);
console.log("MATCHES TESTER -----------------------------------" + typeof urlMatch);
data.push({
title: items.item(i).getElementsByTagName("title").item(0).text,
leftImage: str.match(patt1) !== null ? str.match(patt1)[0] : 'image_news.png',
dataToPass: items.item(i).getElementsByTagName("description").item(0).text,
mp3Test: itemsEnclosureLength > 0 ? items.item(i).getElementsByTagName("enclosure").item(i).getAttribute("url"):'NULL.MP3'
});
console.log("Check this --------------------------"+ mp3Test);
}
BUMP2

The problem was that I was using two counters which had the same value! Silly mistake but...Here's the solution:
var itemsEnclosureLength=items.item(i).getElementsByTagName("enclosure").length;
var itemsEnclosureExists=items.item(i).getElementsByTagName("enclosure");
if (itemsEnclosureExists){
for (n=0; n<itemsEnclosureLength; n++){
mp3=items.item(i).getElementsByTagName("enclosure").item(n).getAttribute("url");
}
}
else{
mp3= 'NULL.mp3';
}

Related

Else statement still running when if statement is true with google script

I have a function that has a name with a set of data and this name is compared to a list of names. If that name is already in the list of names, the data associated with the name replaces the old data. If the name is a name not in the list of names it adds the name and the associated info to the bottom of the list.
For some reason when I run the code with a name already in the list, the original data is replaced and the name and data are added to the bottom of the list. I want to avoid repeating people while also adding new individuals.
var app = SpreadsheetApp;
var activeSheet = app.getActiveSpreadsheet();
var lookup = app.getActiveSpreadsheet().getSheetByName("Lookup");
var issued = app.getActiveSpreadsheet().getSheetByName("Issued");
var name1 = lookup.getRange(12,3).getValue();
var info = lookup.getRange(16,3,1,12).getValues();
for (var j=1;j<105;j++){
var issuedOfficers = issued.getRange(j,11).getValue();
//if the officers name is already recorded in issued the system will replace the current data with updated data
if (issuedOfficers === name1){
issued.getRange(j,1,1,12).setValues(info);
} else {
var lastrow = issued.getLastRow();
issued.getRange(lastrow+1,1,1,12).setValues(info);
break;
}
}
}```
How about this modification?
Modification points:
In your script,
When j is 1 and issuedOfficers === name1 is true, issued.getRange(j,1,1,12).setValues(info) is run. And, when j is 2 and issuedOfficers === name1 is false, issued.getRange(lastrow+1,1,1,12).setValues(info) is run. And the for loop is finished.
When j is 1 and issuedOfficers === name1 is false, issued.getRange(lastrow+1,1,1,12).setValues(info) is run. And the for loop is finished.
I think that this is the reason of your issue. In order to avoid this issue, how about the following modification?
Modified script:
From:
for (var j=1;j<105;j++){
var issuedOfficers = issued.getRange(j,11).getValue();
//if the officers name is already recorded in issued the system will replace the current data with updated data
if (issuedOfficers === name1){
issued.getRange(j,1,1,12).setValues(info);
} else {
var lastrow = issued.getLastRow();
issued.getRange(lastrow+1,1,1,12).setValues(info);
break;
}
}
To:
var names = issued.getRange(1, 11, 105, 1).getValues().flat();
var index = names.indexOf(name1);
if (index > -1) {
issued.getRange(index + 1,1,1,12).setValues(info);
} else {
issued.appendRow(info[0]);
}
In this modification, at first, the values are retrieved from the sheet of issued, and it checks whether name1 is included in the values. By this, the row is updated or the value is appended.
Note:
Please use this script with enabling V8.
References:
flat()
indexOf()
appendRow(rowContents)

conditional splitting of string and word by matching characters in js

I have very long string that contains html as a string , numbers , my special bindings and numbers I want to split my bindings and sentences with spaces separately but my program is separately my bindings and words .
my js code:-
var x = 'hey this is {{name}} and I love to {{write}} and to learn as
much as I can. Now I am trying to separate sentences and my bindings'
var c = x.match(/\s*\S*\s*/g) // this splits words from string including
space
var mt = x.match(/{(.*)}/g); // trying to take out bindings but this don't
work
mt.forEach(function(a){ // taking each bindings separately
var z = x.match(a)
})
console.log(mt)
Somthing like this .. but I know this is totally wrong please help me
I don't have any idea :-
output that I am expecting:-
(5) ["hey this is", "i", "{{name}}", " and I love to ", "{{write}}", " and to learn as ↵ much as I can. Now I am trying to separate sentences and my bindings"]
How can i do this?
Please don't use jquery
Try this:
I've commented my code hoping it would make it easier to read. But do note that this code is far from perfect although it solves your problem.
var rawString = 'hey this is {{name}} and I love to {{write}} and to learn as much as I can. Now I am trying to separate sentences and my bindings';
var arrayRawString = rawString.match(/\s*\S*\s*/g); // this splits words from string including space
var arrayPlaceholder = rawString.match(/{(.\S*)}+/g); // trying to take out bindings but this don't work
// to store the final output
var separedArray = [];
// keeping track of the index to stich the array up
var posStart = 0;
var posEnd = 0;
arrayPlaceholder.forEach(function(arg){ // taking each bindings separately
// length of the array that holds placeholder (bindings)
var arsLength = arrayRawString.length;
for(var i = 0; i < arsLength; ++i) {
// if the provided text matches the original array's element
if(arrayRawString[i].match(arg)){
// to store the index
posEnd = arrayRawString.indexOf(arrayRawString[i]);
// join the pieces together upto the index defined
var res = arrayRawString.slice(posStart, posEnd).join('');
// to indicate whether the stored string is the placeholder
var flag = true;
// store the string obtained
separedArray.push(res.replace(arrayPlaceholder[(arrayPlaceholder.indexOf(arg) - 1) < 0 ? 0 : arrayPlaceholder.indexOf(arg) - 1 ], ''));
// check if the string still has placeholder (bindings)
// to remove it
for(var j = 0; j < arg.length; ++j) {
if(res[j] !== arg[j]) {
flag = !flag;
}
}
if ( flag ) {
separedArray.push(arg);
}
// last end position is the start position for next round
posStart = posEnd;
// because the loop runs only arrayPlaceholder.length times
// it solves the problem of last part not getting pushed to the final array
if( arrayPlaceholder[arrayPlaceholder.length-1] === arg ) {
res = arrayRawString.slice(posStart, arrayRawString.length).join('');
separedArray.push(res.replace(arg, ''));
}
}
}
});
console.log(separedArray);

TypeError: 'undefined' is not an object in Javascript

I have a piece of Javascript code that assigns string of values to a string array.
Unfortunately if I try to add more than one string to the array, my UI simulator(which runs on JS code) closes unexpectedly. I have tried debugging but I cannot find anything. I am attaching that piece of code where the issue is. may be you guys could find some flaw? On the pop up button click the values I selcted on the UI should get stored in the array and I have a corressponding variable on the server side to handle this string array.
_popupButtonClick: function (button) {
var solutions = this._stateModel.get('solutionName');
var i;
var solutionsLength = solutions.length;
var selectedSolution = [solutionsLength];
this.clearPopupTimer();
if (button.position === StatusViewModel.ResponseType.Ok) {
for(i=0;i<solutionsLength;i++)
{
if(this._list.listItems[i].selected)
{
selectedSolution[i] = this._list.listItems[i].options.value;
}
}
this._stateModel.save({
selectedsolutions: selectedSolution,
viewResponse: StatusViewModel.ResponseType.Ok
});
} else {
this._stateModel.save({
viewResponse: StatusViewModel.ResponseType.Cancel
});
}
}
Change
var selectedSolution = [solutionsLength];
to
var selectedSolution = [];
This makes your array have an extra item that might be causing a crash.
Also,
you have an
if(this._list.listItems[i].selected)
{
selectedSolution[i] = this._list.listItems[i].options.value;
}
But no corresponding else, so your array has undefined values for i which are not entering the if.
Maybe adding an empty string might solve it:
if(this._list.listItems[i].selected)
{
selectedSolution[i] = this._list.listItems[i].options.value;
}
else
{
selectedSolution[i] = "";
}
The code is looking fine but there seems to be a piece of code which can cause error. For example, you are assigning var selectedSolution = [solutionsLength]; and for example solutionsLength is 5 then your loop runs for 5 times
for(i=0;i<solutionsLength;i++) // runs for 5 times
{
if(this._list.listItems[i].selected)
{
// but selectedSolution = [5]; which is on 0th index and from 1st to 4th index it is undefined
selectedSolution[i] = this._list.listItems[i].options.value;
}
}
So you can try to use push() like
selectedSolution.push(this._list.listItems[i].options.value);
and on initialization change it like,
var selectedSolution = [];
Hopefully this will solve your problem.
var selectedSolution = [solutionsLength];
keeps the value in the selectedSolution variable.
var selectedSolution = [3];
selectedSolution[0] gives the values as 3
So make it simple
var selectedSolution = [];

unable to search for array items

In this program I am unable to search for items in an array. The db variable is already defined. I am unable to get into the search function and run it. Just curious why this might be happening. I am able to run the first validate function but then stops and will not perform the rest of the code.
// Create privatized scope using a self-executing function
(function() {
console.log("hello");
// Variable initialization (DO NOT FIX ANY OF THE BELOW VAR's)
var resultsDIV = document.getElementById("results"),
searchInput = document.forms[0].search,
currentSearch = '';
// Validates search query
var validate = function (query) {
console.log("validate");
// Trim whitespace from start and end of search query
query = query.trim();
// Check search length, must have 3 characters
if (query.length < 3) {
alert("Your search query is too small, try again.");
}else{
search(query);
// (DO NOT FIX THE LINE DIRECTLY BELOW)
searchInput.focus();
}
console.log("test");
};
console.log("outside search function");
// Finds search matches
var search = function (query) {
console.log("In search function");
// split the user's search query string into an array
var queryArray = query.split(" ");
// array to store matched results from database.js
var results = [];
// loop through each index of db array
for (var i = 0, j = db.length; i < j; i++) {
console.log(i);
// each db[i] is a single video item, each title ends with a pipe "|"
// save a lowercase variable of the video title
var dbTitleEnd = db[i].indexOf('|');
var dbItems = db[i].toLowerCase().substring(0, dbTitleEnd);
}
// loop through the user's search query words
// save a lowercase variable of the search keyword
for (var ii = 0, jj = queryArray.length; ii < jj; ii++) {
var qItem = queryArray[ii].toLowerCase();
}
// is the keyword anywhere in the video title?
// If a match is found, push full db[i] into results array
var compare = dbItems.indexOf(qItem);
if (compare !== -1) {
results = results.push(db[i]);
}
results.sort();
// Check that matches were found, and run output functions
if (results.length === 0) {
noMatch();
} else {
showMatches(results);
}
};
// Put "No Results" message into page (DO NOT FIX THE HTML VAR NOR THE innerHTML)
var noMatch = function() {
var html = '' +
'<p>No Results found.</p>' +
'<p style="font-size:10px;">Try searching for "JavaScript". Just an idea.</p>'
;
resultsDIV.innerHTML = html;
};
// Put matches into page as paragraphs with anchors
var showMatches = function (results) {
// THE NEXT 4 LINES ARE CORRECT.
var html = '<p>Results</p>',
title,
url
;
// loop through all the results search() function
for (var i = 0, j = results.length; i < j; i++) {
// title of video ends with pipe
// pull the title's string using index numbers
var titleEnd = results[i].indexOf('|');
title = results[i].subString(0, titleEnd);
// pull the video url after the title
url = results[i].substring(results[i].indexOf('|') + 1, results[i].length);
// make the video link - THE NEXT LINE IS CORRECT.
html += '<p><a href=' + url + '>' + title + '</a></p>';
resultsDIV.innerHTML = html; //THIS LINE IS CORRECT.
}
};
console.log("start of program");
/***** start of program *******/
// The onsubmit event will be reviewed in upcoming Course Material.
// THE LINE DIRECTLY BELOW IS CORRECT
document.forms[0].onsubmit = function(){
var query = searchInput.value;
validate(query);
// return false is needed for most events - this will be reviewed in upcoming course material
// THE LINE DIRECTLY BELOW IS CORRECT
return false;
};
})();
I checked your code and everything is there but somehow all wrongly connected. It seems that you have completely wrong concept about for loops. I did several minor changes:
query is trimmed on reading because we need it not just in validator
validator:
if query is too short set focus back
it validated but also allowed operation to continue in case of error - changed
changed to isValid() and checked in onsubmit handler
search:
wrong concept of for loops
you retrieve dbTitleEnd/dbItems and than overwrite them by the next one
there is no need to do results = results.push(db[i]); but just `results.push(db[i]);
subString() corrected to substring()
console.log() messages are left in
See Example in jsFiddle.

Cant figure out search error

working on this, too. I've fixed the spelling and (i think) the bracket errors. Also fixed a couple errors I saw that stood out, but didn't get too far. I'm still stumped as to where to go with it next.
(function(){
// Variable initialization (DO NOT FIX ANY OF THE BELOW VAR's)
var resultsDIV = document.getElementById("results"),
searchInput = document.forms[0].search,
currentSearch = ''
;
// Validates search query
var validate = function(query){
// Trim whitespace from start and end of search query
while (query.charAt[0] === " "){
query = query.substring(1, query.length);
};
while (query.charAt(query.length-1) === ""){
query = query.substring(0, query.length - 1);
};
// Check search length, must have 3 characters
if (query.length < 3){
alert ("Your search query is too small, try again.");
// (DO NOT FIX THE LINE DIRECTLY BELOW)
searchInput.focus();
return;
};
search (query);
};
// Finds search matches
var search = function (query){
// split the user's search query string into an array
var queryArray = query.join(" ");
// array to store matched results from database.js
var results = [];
// loop through each index of db array
for(var i=0, j=db.length; i<j; i++){
// each db[i] is a single video item, each title ends with a pipe "|"
// save a lowercase variable of the video title
var dbTitleEnd = db[i].indexOf('|');
var dbitem = db[i].tolowercase().substring(0, dbTitleEnd);
// loop through the user's search query words
// save a lowercase variable of the search keyword
for(var ii=0, jj=queryArray.length; ii<jj; ii++){
var qitem = queryArray[ii].tolowercase();
// is the keyword anywhere in the video title?
// If a match is found, push full db[i] into results array
var compare = dbitem.indexOf(qitem);
if(compare !== -1){
results.push(db[i]);
};
};
};
};
results.sort();
// Check that matches were found, and run output functions
if(results.length = );{
noMatch();
}else{
showMatches(results);
};
// Put "No Results" message into page (DO NOT FIX THE HTML VAR NOR THE innerHTML)
var noMatch = function(){
var html = ''+
'<p>No Results found.</p>'+
'<p style="font-size:10px;">Try searching for "JavaScript". Just an idea.</p>'
;
resultsDIV.innerHTML = html;
};
// Put matches into page as paragraphs with anchors
var showMatches = function(results){
// THE NEXT 4 LINES ARE CORRECT.
var html = '<p>Results</p>',
title,
url
;
// loop through all the results search() function
for(var i=0, j=results.length; i<j; i++){
// title of video ends with pipe
// pull the title's string using index numbers
titleEnd = results[i].indexOf('|');
title = results[i].subString(0, titleEnd);
// pull the video url after the title
url = results[i].substring(results[i].indexOf('|')+1, results[i].length);
// make the video link - THE NEXT LINE IS CORRECT.
html += '<p><a href=' + url + '>' + title + '</a></p>';
};
resultsDIV.innerHTML = html; //THIS LINE IS CORRECT.
};
// The onsubmit event will be reviewed in upcoming Course Material.
// THE LINE DIRECTLY BELOW IS CORRECT
document.forms[0].onsubmit = function(){
var query = searchInput.value;
validqte(query);
// return false is needed for most events - this will be reviewed in upcoming course material
// THE LINE DIRECTLY BELOW IS CORRECT
return false;
;
})();
There are a few syntax errors which should prevent this from running at all.
// syntax error
var results = ();
// should be
var results = [];
Also it appears that the definition of showMatches ends with an unmatched right parenthesis.
Given that somehow the code is running with these syntax errors (and possibly others I didn't notice), the (a) glaring issue is:
if (results.length = 0) {
Yeah, that's an assignment, not a comparison. You just set the array's length to zero, which effectively clears it. This both fails the length test here (returning 0), then hands the now empty array off to be displayed as results, but of course it's now an array of length 0.
On another note, probably not an actual problem but I can't help it. The while loop business to trim the string? Yeah, don't do that. Use trim. If you need a polyfill there's always:
if (!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g, '');
};
}

Categories

Resources