I am having some issues using string interpolation in a regex, however I have also tried to log it to the console and I can see that I am doing it incorrectly.
I am trying to loop through an array of weather types to see if my API request returned a type of weather which requires me to add a class to one of my elements in the UI.
I iniitally thought the issue was using array[x] in the regex, but I have assigned this to a variable p and am still getting the same result.
let weatherTypes = ['rain', 'clouds', 'snow', 'clear', 'thunderstorm'];
for (var x= 0; x <= weatherTypes.length; x++) {
let p = weatherTypes[x];
console.log(p)
var searchPattern = `/${p}/i`;
var result = this.state.description.match(searchPattern);
console.log(`splash--weather-${p}`);
if(result !== null) {
var element = document.getElementById("splashContact");
element.classList.add(`splash--weather-${weatherTypes[0]}` );
}
}
The logic to add the class works when I abstract it out of the for loop so I know that part is working fine.
Can somebody please point me in the right direction?
edit Have now used backticks instead of quotation marks
searchPattern is a string so you just need to use the RegExp constructor before using it.
var searchPattern = `${p}/i`;
var searchPatternRegex = RegExp(`${searchPattern}`);
Related
I am trying to split up a string on /* and then to split up those segments on */
So that I can separate out all of the comments as I want this code to be able to take all of the comments out of the string and then put it back together.
The problem is though I keep getting this .append error which I am pretty sure is because I have made a silly syntax error but I am struggling to find it and any help would be greatly appreciated.
JS
contents = "if for /* else */ . = == === /* return */ function"
var start = /\/\*/gi;
var end = /\*\//gi;
var commentsRemovedSec2 = [];
var commentsRemovedSec1 = contents.split(start);
console.log(commentsRemovedSec1);
for (var i = 0; i < commentsRemovedSec1.length; i++) {
var z = ""
var x = commentsRemovedSec1[i]
var y = x.split(start)
z = y[0]
commentsRemovedSec2.append(z);
};
console.log(commentsRemovedSec2);
Unfortunately .append() isn't an Array method.
Instead use the Array method .push().
commentsRemovedSec2.push(z)
The push() method adds one or more elements to the end of an array and
returns the new length of the array. MDN
My JSON.parse is successful when it is called first. But from 2nd call, unexpected token error occurs.
I found from the search in stackoverflow some explanation for other's question below..
"If you parse it again it will perform a toString-cast first so you're parsing something like "[object Object"] which explains the unexpected token o "
How can i make the fresh parse. my code is like below.
var musicEntry="";
function parsing(){
...
for(var i=0;i<musicList.length;i++){
musicEntry=musicEntry+ '{"fileName":"'+musicList[i].title+'"},';
}
.....
var musicJsonObjString='{"music":['+ musicEntry +']}';
musicJsonObj=JSON.parse(musicJsonObjString);
}
I'd recommend using JSON.stringify() instead of trying to write your own JSON encoder. Whilst your approach might now work with the trailing comma issue fixed, you'll also need to guard against reserved characters in your music title attribute.
Simply build a JavaScript object (or array) and give it to JSON.stringify(obj)
Working example
var musicList = [{
title: 'foo'
}, {
title: 'bar'
}];
var array = [];
for (var i = 0; i < musicList.length; i++) {
array.push({fileName: musicList[i].title})
}
var musicJsonObjString = JSON.stringify({music: array});
var musicJsonObj = JSON.parse(musicJsonObjString);
console.log("music", musicJsonObj);
You need to remove last comma from your array:
var musicJsonObjString='{"music":[' + musicEntry.substr(0, musicEntry.length - 1 ) + ']}';
So, I'll admit to being a bit of a JS noob, but as far as I can tell, this should be working and it is not.
Background:
I have a form with 3 list boxes. The list boxes are named app1, db1, and db2. I'm using javascript to allow the user to add additional list boxes, increasing the name tag for each additional select box.
When I add additional app named boxes, the value increments properly for each additional field. If I try to add addtional db named selects, it fails to recognize the 2nd tag on the first loop through the array. This causes me to end up with 2 elements named db2. On each subsequent tag, it is recognized properly and is properly incremented.
Here is the HTML for the db1 tag:
<select name="db1">
*options*
</select>
And db2:
<select name="db2">
*options*
</select>
The tags are identical. Here is the function that I am using to figure out the next number in the sequence (note: tag is either app or db, tags is an array of all select tag names in the DOM, if I inspect tags, it gives me ['app1', 'db1', 'db2', '']):
function return_select_name(tag, tags) {
matches = new Array();
var re = new RegExp(tag + "\\d+", "g");
for (var i = 0; i < tags.length; i++) {
var found = re.exec(tags[i]);
if (found != null) {
matches.push(found[0]);
}
}
matches = matches.sort();
index = parseInt(/\d+/.exec(matches.last())) + 1;
index = tag + index;
return index;
}
If I add an app tag, it will return 'app2'. If I search for a db tag, it will return 'db2' on the first time through, db3 on the 2nd, etc, etc.
So basically, I'm sure I'm doing something wrong here.
I'd handle it by keeping a counter for db and a counter for app to use to generate the names.
var appCounter = 1;//set this manually or initialize to 0 and
var dbCounter = 2;//use your create function to add your elements on pageload
Then, when you go to create your next tag, just increment your counter and use that as the suffix for your name:
var newAppElement = document.createElement('select');
newAppElement.name = 'app' + (++appCounter);
..
// --OR for the db element--
var newDbElement = document.createElement('select');
newDbElement.name = 'db' + (++dbCounter );
..
The problem you are getting is that regex objects are stateful. You can fix your program by putting the regex creation inside the loop.
function return_select_name(tag, tags) {
matches = new Array();
// <-- regex was here
for (var i = 0; i < tags.length; i++) {
var re = new RegExp(tag + "\\d+", "g"); //<--- now is here
var found = re.exec(tags[i]);
if (found != null) {
matches.push(found[0]);
}
}
matches = matches.sort();
index = parseInt(/\d+/.exec(matches[matches.length-1])) + 1; //<--- I dont think matches.last is portable, btw
index = tag + index;
return index;
}
In any case, if I were to do this myself, I would probably prefer to avoid the cmplicated text matching and just store the next tag indices in a variable or hash map.
Another suggestion: if you put parenthesis in your regex:
// /tag(\d+)/
var re = new RegExp(tag + "(\\d+)", "g");
Then you can use found[1] to get your number directly, without the extra step afterwards.
I know this has already been answered, but I put this together as a proof of concept.
http://jsfiddle.net/zero21xxx/LzyTf/
It's an object so you could probably reuse it in different scenarios. Obviously there are ways it could be improved, but I thought it was cool so I thought I would share.
The console.debug only works in Chrome and maybe FF.
This may have been asked in the past but I couldnt find a suitable answer. What I am looking for is a method to extract parameters from an sql query such as below. The queries will always be an EXEC statement followed by the query name, and possible parameters.
Here is an example of what I may recieve
EXEC [dbo].[myProcedure] #Param1
This could also be as follows
EXEC [dbo].[myProcedure] #Param1, #Param2, #Param3
Those are the only types of queries that the input will take. As for why I am doing this, well thats another question all together, and I am pretty set on going down this route.
What I am looking for is to be able to take the above strings and produce an array of values such as
['#Param1','#Param2','#Param3',....]
I originally tried to just parese using a simple while statement but I seem to have huge issues there.
I hope this question makes sense,
Cheers,
Nico
[Edit]
Sorted this by using the following statement
function eParams(e) {
var i = e.indexOf('#');
if (i <= 0)
return;
e = e.substring(i);
var p = e.split(',');
var eList = [];
var s = '';
for (var i = 0, j = p.length - 1; i <= j; i++) {
var sP = p[i].trim();
if (sP.indexOf('#') < 0)
continue;
eList.push(sP);
}
}
var str = 'EXEC [dbo].[myProcedure] #Param1, #Param2, #Param3';
(str).match(/(#[^\s,]+)/g);
will return an array.
var s = "EXEC [dbo].[myProcedure] #Param1, #Param2, #Param3";
var i = s.indexOf('#');
var a = s.substr(i).split(/\s*,\s*/);
(error checking omitted)
I send a string from a server to the Firefox Browser in the format below:
"KEY:a1 VAL:123.45"
And this string can contain many such records.
Here is the code I have written:
var e;
var reply = request.responseText;
var txt = "", tab, key = "", val = "";
var x = reply.getElementsByTagName("KEY:");
for(i = 0; i < x.length; i++)
{
txt = x[i].childNodes[0].nodeValue; // "KEY:%c%c VAL:%.2F"
tab = txt.split(":");
key = "table_" + tab[1].substring(0,1);
val = tab[2];
e = document.getElementById(key);
e.innerHTML = val;
e.style.display = "block";
}
val displays "KEY:a1 VAL:123.45" instead of the expected "123.45" (and of course the key variable is also wrong, not matching a table cell, just picking the first one in the table).
I don't even know how to display the key and val values (document.write() and alert() do nothing and I don't see how to trace this code in Firefox).
Any idea, tip, correction, or code example is welcome but please don't recommend using any library, I want to do it with little code.
EDIT: from the two comments, I understand that there are two distinct ways to proceed: either using DOM objects and HTML tags, or using 'strings'. I would prefer to keep using the format above, so please guide me to a 'string' solution. Thanks!
You can use a simple regular expression to extract the information from the string:
var value = "KEY:a1 VAL:123.45",
pattern = /KEY:(\S+) VAL:(.+)$/g;
var result = pattern.exec(value);
// result[1] == 'a1'
// result[2] == '123.45'
In your case, you'd use request.responseText instead of value.