Why does my javascript else statement stop working - javascript

The first if-else statement works as expected, when the address bar variables are there it does the if part and when not there does the else...however, right after the VAR lines that split everything up every else statement i put in does not work
var hasVars = 0;
var loc = window.location.href;
if(loc.indexOf('?')>-1) { hasVars = 1; }
if(hasVars==1) { alert("ttt"); }
else { alert("eee"); }
var query = loc.slice(loc.indexOf('?') + 1);
var vars = query.split('&');
var pair = vars[0].split('=');
var data1 = pair[1].split('.');
if(hasVars==1) { alert("ttt"); }
else { alert("eee"); }
I commented every line out and put them back in and the problem seems to be with the data1 variable line, commented out it works fine but with it the else statement doesn't run

The var query (...) part of your code will only work when there are query parameters. So it is having problems when there are none. One solution would be to place an if there as well.
var hasVars = 0;
var loc = window.location.href;
if(loc.indexOf('?')>-1) { hasVars = 1; }
if(hasVars==1) { alert("ttt"); }
else { alert("eee"); }
if (hasVars==1) { // added this
var query = loc.slice(loc.indexOf('?') + 1);
var vars = query.split('&');
var pair = vars[0].split('=');
var data1 = null;
if (pair[1] != undefined) { // added this for: "page?var" cases
data1 = pair[1].split('.');
} // added
} // added
if(hasVars==1) { alert("ttt"); }
else { alert("eee"); }
The problem you had, in detail:
When there are no query parameters, query would be just the URL. Let me explain step by step. Example page: http://example.com/page
query -> 'http://example.com/page'
vars -> ['http://example.com/page']
pair -> ['http://example.com/page']
The problem would be in:
var data1 = pair[1].split('.');
As pair has no item in pair[1]. The code above would be the same as undefined.split('.'), what gives a runtime error, thus preventing the following lines (and the second if you asked) from executing.

What exactly do you mean the statement doesn't work? Neither of the alerts is fired?
I'm guessing pair[1] does not exist and is causing an exception; can you post a sample query?

The reason the second alert doesn't fire is that query is undefined when hasVars !== 1. This causes query to be undefined, which means it is not a string and doesn't have string methods (like split). Attempting to use string methods on a non-string object throws errors, which prevent the rest of your code from running.
To solve this, define query (and the rest of your strings) as:
var query = hasVars ? loc.slice(loc.indexOf('?') + 1) : '';
var vars = hasVars ? query.split('&') : '';
var pair = hasVars ? vars[0].split('=') : '';
var data1 = hasVars ? pair[1].split('.') : '';
This uses the ternary operator (?:) to initialize query as an empty string if hasVars is not 1.
As query (and the rest of the strings) is now defined as a string one way or the other, no errors are thrown.

Related

Getting query string parameters from clean/SEO friendly URLs with JavaScript

I've recently switched my site to use clean/SEO-friendly URLs which has now caused me some issues with a JavaScript function I had for grabbing the query string parameters.
Previously I had been using this function:
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
return (false);
}
Which worked fine on things like this as you could just call getQueryVariable("image") and return "awesome.jpg".
I've been playing with the indexOf(); function to try and grab the relevant parameters from the current URL, eg:
var url = window.location.pathname;
var isPage = url.indexOf("page") + 1;
In an attempt to get the array index number of the "page" parameter, and then plus 1 it to move along to the value of that (?page=name > /page/name/)
JavaScript isn't my main language, so I'm not used to working with arrays etc and my attempt to turn this into a new function has been giving me headaches.
Any pointers?
How about something like this? It splits the path and keeps shifting off the first element of the array as it determines key/value pairs.
function getPathVariable(variable) {
var path = location.pathname;
// just for the demo, lets pretend the path is this...
path = '/images/awesome.jpg/page/about';
// ^-- take this line out for your own version.
var parts = path.substr(1).split('/'), value;
while(parts.length) {
if (parts.shift() === variable) value = parts.shift();
else parts.shift();
}
return value;
}
console.log(getPathVariable('page'));
This can be done formally using a library such as router.js, but I would go for simple string manipulation:
const parts = '/users/bob'.split('/')
const name = parts[parts.length - 1] // 'bob'

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 = [];

Function to return a list - issue with filtering the output

I am trying to output only articles if authorsId = authorId.
Beside that the whole function works exactly as I want, here it is:
The general idea is to limit access to only own articles.
So, my question is: how do I limit the results to show only articles written by the owner of the page we are on (authorsId = authorId).
function ArticlesListReturn(returned) {
xml = returned.documentElement;
var rel = document.getElementById('related_category_articles');
rel.options.length = 0;
var status = getXMLData('status');
var title = '';
var id = '';
var authorid = '';
if (status == 0) {
alert("%%LNG_jsArticleListError%%" + errormsg);
} else {
var authorid = document.getElementById("authorid").value; // Serge
// authorsid = getNextXMLData('authors',x);
for (var x = 0; x < xml.getElementsByTagName('titles').length; x++) {
title = getNextXMLData('titles', x);
id = getNextXMLData('ids', x);
authorsid = getNextXMLData('authors', x);
alert(authorsid) // authors of each article - it returns the proper values
alert(authorid) // author of the page we are on - it returns the proper value
var count = 0;
rel.options[x] = new Option(title, id, authorid); // lign that returns results
title = '';
id = '';
authorid = '';
}
}
I suspect the problem is when you try performing a conditional statement (if/then/else) that you are comparing a number to a string (or a string to a number). This is like comparing if (1 == "1" ) for example (note the double quotes is only on one side because the left would be numeric, the right side of the equation would be a string).
I added a test which should force both values to be strings, then compares them. If it still gives you problems, make sure there are no spaces/tabs added to one variable, but missing in the other variable.
Also, I changed your "alert" to output to the console (CTRL+SHIFT+J if you are using firefox). The problem using alert is sometimes remote data is not available when needed but your alert button creates a pause while the data is being read. So... if you use alert, your code works, then you remove alert, your code could reveal new errors (since remote data was not served on time). It may not be an issue now, but could be an issue for you going forward.
Best of luck!
function ArticlesListReturn(returned) {
xml = returned.documentElement;
var rel = document.getElementById('related_category_articles');
rel.options.length = 0;
var status = getXMLData('status');
var title = '';
var id = '';
var authorid = '';
if (status == 0) {
alert("%%LNG_jsArticleListError%%" + errormsg);
} else {
var authorid = document.getElementById("authorid").value; // Serge
// authorsid = getNextXMLData('authors',x);
for (var x = 0; x < xml.getElementsByTagName('titles').length; x++) {
title = getNextXMLData('titles', x);
id = getNextXMLData('ids', x);
authorsid = getNextXMLData('authors', x);
console.log("authorsid = "+authorsid); // authors of each article - it returns the proper values
console.log("authorid = "+authorid); // author of the page we are on - it returns the proper value
if( authorsid.toString() == authorid.toString() )
{
rel.options
var count = 0;
console.log( authorsid.toString()+" equals "+authorid.toString() );
rel.options[rel.options.length] = new Option(title, id, authorid); // lign that returns results
}
else
{
console.log( authorsid.toString()+" NOT equals "+authorid.toString() );
}
title = '';
id = '';
authorid = '';
}
Did you check the console for messages? Did it correctly show authorid and authorsid?
I have edited the script and made a couple of additions...
The console will tell you if the conditional check worked or not (meaning you will get a message for each record). See the "if/else" and the extra "console.log" parts I added?
rel.options[x] changed to equal rel.options[rel.options.length]. I am curious on why you set rel.options.length=0 when I would instead have done rel.options=new Array();

Find any variable that is undefined and hide from url string

I'm currently building a URL string from form inputs to look something similar to this:
api/search/127879/11-28-2013/7/2/undefined/undefined/undefined/LGW/null
How would i find any or all variables that === to undefined and then remove from these from the string above?
if you dont want to chage logic of building url than just make use of replace function of javascript
var str = "api/search/127879/11-28-2013/7/2/undefined/undefined/undefined/LGW/null";
var res = str.replace(/undefined\//gi,"");
If you are generating string yourself, then check before appending it to urlString.
If you get the string from server, then do this:
var finalUrl = "";
var urlStr= "api/search/127879/11-28-2013/7/2/undefined/undefined/undefined/LGW/null";
var urlArray = urlStr.split('/');
for (i = 0, i = urlArray.length; i ++) {
if(urlArray[i] === undefined)
{
//do nothing
}
else
{
finalUrl += urlArray[i];
}
}
Hope this helps.

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