Jquery code breaks when using replace() function - javascript

I have a simple code that is separating book title from serial using the ":" as separator. This is really a straight forward solution and should work. On my website it's working but stopping when using german umlauts in the book title. So I created a JSFiddle to find out what's going on but the code breaks whenever I'm using the replace() function.
html:
<div id="title">Die Träne des Fressers: Weiße Königin</div>
Title:<div id="output_title">output title</div>
Serial:<div id="output_serial">output serial</div>
js:
title_input = $("#title").text();
title = title_input.match(/[a-z\s,äöüß-]*.*:/i);
serial = title_input.match(/:\s?[a-z\s,äöüß-]*/i);
title.replace(/\:/g,'');
//serial = serial.replace(/[:|\.]+/g, "").trim();
$("#output_title").text(title);
$("#output_serial").text(serial);
I do not understand what's going on. Could someone explain it to me?

The problem is that .match() is returning an array not a string as you're expecting. You'll need to check for this and select the matching string (if applicable) before calling .replace().
Currently by adding a bit of logging:
title_input = $("#title").text();
title = title_input.match(/[a-z\s,äöüß-]*.*:/i);
serial = title_input.match(/:\s?[a-z\s,äöüß-]*/i);
console.log(title.length); // <-- Logging
We can see that title is the following:
["Die Träne des Fressers:", index: 0, input: "Die Träne des Fressers: Weiße Königin"]
For your code to work, you need to get the first element of the title array (if available) before calling .replace():
title_input = $("#title").text();
title = title_input.match(/[a-z\s,äöüß-]*.*:/i);
serial = title_input.match(/:\s?[a-z\s,äöüß-]*/i);
if(title && title.length) {
title = title[0];
title.replace(/\:/g,'');
}
$("#output_title").text(title);
$("#output_serial").text(serial);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="title">Die Träne des Fressers: Weiße Königin</div>
Title:<div id="output_title">output title</div>
Serial:<div id="output_serial">output serial</div>
Extra Note: To ensure you don't get an undefined type error, it's a good idea to ensure that title exists and is not an empty array as noted by the if(title && title.length) line.

Like #Pointy mentioned in comments the match() return an array and The first element of the array (element 0) will contain the matched substring so you have to select first element by addinng [0] :
title = title_input.match(/[a-z\s,äöüß-]*.*:/i)[0];
serial = title_input.match(/:\s?[a-z\s,äöüß-]*/i)[0];
Also the replace() method will return the new string generated after replacement, so you have to assign it to your variable :
title = title.replace(/\:/g,'');
hope this helps.
Updated fiddle.

Variable title exists only when script can find one of this symbols and title isn't string - it's array. You can't use replace on null or on array.
This should works:
var title = $("#title").text();
title = title.replace(/[a-z\s,äöüß-]*.*:/i,'');
And if you want to split this string you should use .split(':') function.

Related

Dynamic from fields using reactive forms in Angular?

I have a scenario like Need to edit the single quotes values (only single quotes values),
So I extracted the single quotes values using regex and prepare the reactive dynamic form.
onclick of performing edit button will show old step name above, new step name below, submit step will replace the step name in the original array.
WOrking fine as expected in few scenarios according to my approach, but in scenarios, I realized whatever algorithm I am following does not fulfill my requirement.
Below are the test cases
Test case 1:
Step Name: "Then I should hire an employee using profile '1' for 'USA'",
// Here --> '1', 'USA' values are editable
Test case 2: "And Employee should be hired on '01' day of pay period '01' of 'Current' Fiscal"
// '01', '01', 'Current'
Issues: in test case 2 if I tried to edit second 01 it is editing the first 01
I try to solve the perform edit function with help of indexof, substring functions
this.replaceString = this.selectedStep.name;
this.metaArray.forEach((element: any) => {
var metaIndex = this.replaceString.indexOf(element.paramValue);
if (metaIndex !== -1) {
const replaceValue = this.stepEditForm.controls[element['paramIndex']].value;
this.replaceString = this.replaceString.substring(0, metaIndex) + replaceValue + this.replaceString.substring(metaIndex + (element.paramValue.length));
}
});
but in indexof always find the first occurrence of a value in a string. So I realized my approach is wrong on performed it function
please find the attachment for the code
https://stackblitz.com/edit/angular-reactive-forms-cqb9hy?file=app%2Fapp.component.ts
So Can anyone please suggest to me how to solve this issue,
Thanks in advance
I added a function called matchStartingPositions that returns the starting position indexes of each match. Using this method you can then perform your edit by replacing the string just as you do, but we'll find the proper match to be replaced at the given position.
So in your line
var metaIndex = this.replaceString.indexOf(element.paramValue);
we can then add a second parameter to indexOf, that is the starting point:
var metaIndex = this.replaceString.indexOf(element.paramValue, startingPositions[element.paramIndex]);
The function for getting the index positions just looks for those single quotes in a given string:
matchStartingPositions(str) {
let count = 0;
let indices = [];
[...str].forEach((val, i) => {
if (val === "'") {
if (count % 2 == 0) {
indices.push(i);
}
count++;
}
});
return indices;
}
Here it is in action:
https://angular-reactive-forms-xhkhmx.stackblitz.io
https://stackblitz.com/edit/angular-reactive-forms-xhkhmx?file=app/app.component.ts

How can I modify my <textarea> html value based on user input

I have a html textarea element in my page where user gives comma separate values. for example below.
A-48402,AA,SBAFL,AA+,USD,,
From javascript (which I prefer) I am applying logic to check if the last row value is blank (separated by comma only) then to put a String value 'Y'. Thus I am writing the below
var data = document.getElementById('txid').value;
rows = data.split('\n');var row1 = rows[0];row1Values=row1 .split(',');
Then I am applying logic to verify whether the last value for every row is blank or not, which is actually blank, then adding the below.
row_values.push('Y');
It is reflecting in debugger.
But what I see is the value 'Y' in the Java action class is not reflecting and showing usual 'Y' while the page submit. How can I add this value 'Y' in every rows end (where there is blank) so that it will be visible in action class?
String Data = request.getParameter('mbs_inst_data');
This data is populated with the same blank values.
If you're only checking for the last row then the only case that would happen is when it's ,,
so you can just do a simple check
let data = 'A-48402,AA,SBAFL,AA+,USD,,'
data = data.split(',')
let lastRowIsBlank = data[data.length-2] === ""
// we are doing length - 2 because in your situation we have 2 ""
// since you have two commas. If you have only 1 comma we would
// the same steps but with length - 1
if(lastRowIsBlank) data[data.length-2] = "Y"
return data.toString()
You can use it like this.
<p id="demo">Visit Microsoft! ,,</p>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
var str = document.getElementById("demo").innerHTML;
var res = str.replace(/,,$/, ',Y');
document.getElementById("demo").innerHTML = res;
}
</script>
Output
Visit Microsoft! ,Y
I guess this would help you.

set expected result as true when find in a string partly correct protractor

Hello everyone I got following code:
it('Search for string', function () {
var MySearch = element(by.model('searchQuery'));
MySearch.sendKeys('Apple Pomace');
expect(MySearch.getAttribute('value')).toBe('Apple Pomace');
element(by.buttonText('Search')).click();
//browser.pause();
var optionTexts = element.all(by.repeater('product in products')).map(function (Options) {
return Options.getText();
});
optionTexts.then(function (array){
expect(array).toContain("Apple Pomace");
});
});
then I get as result:
[ 'Apple Pomace\nFinest pressings of apples. Allergy disclaimer: Might contain traces of worms. Can be sent back to us for recycling.\n0.89' ]
now I want to check if the string contains Apple Pomace
I have tried following code:
expect(array).toContain('Apple Pomace');
then I get:
Expected [ 'Apple Pomace
Finest pressings of apples. Allergy disclaimer: Might contain traces of worms. Can be sent back to us for recycling.
0.89' ] to contain 'Apple Pomace'. <Click to see difference>
how do I set the test to true even if the whole string doesn't match my result?
or validate the string to the first "\" ?
code
Thank you in advance
First of all element.all(by.repeater('product in products')).getText() will return array of strings.If you use toContain matcher on the array, it will check for the whole string to be present in the array.
In your case, you need to check if the entire array has any string that matches the word Apple Pomace. To achieve this, you need to transform the result array into a string and then apply toContain matcher on it.
var displayedResults = element.all(by.repeater('product in products')).getText()
.then(function(resultArray){
return resultArray.join(); // will convert the array to string.
})
expect(displayedResults).toContain("Apple Pomace");
Hope this might help you!

extract vimeo video id from the url

Though this question is available on SO, I am facing a little problem.I failed to extract the vimeo id using vimeo regex used here: Vimeo Regex
My codes I,m using now:
function vimeoProcess(url){
var vimeoReg = /https?:\/\/(?:www\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|)(\d+)(?:$|\/|\?)/;
var match = url.match(vimeoReg);
if (match){
console.log(match[3]);
}else{
return "<span class='error'>error</span>";
}
}
It does not consoles any thing.
Can any one help?
This "magical regex" is not so magical. It does not work with the URL you're using, for instance.
Here's another parser I just set up :
var urls =
[
"https://vimeo.com/11111111",
"http://vimeo.com/11111111",
"https://www.vimeo.com/11111111",
"http://www.vimeo.com/11111111",
"https://vimeo.com/channels/11111111",
"http://vimeo.com/channels/11111111",
"https://vimeo.com/channels/mychannel/11111111",
"http://vimeo.com/channels/yourchannel/11111111",
"https://vimeo.com/groups/name/videos/11111111",
"http://vimeo.com/groups/name/videos/11111111",
"https://vimeo.com/album/2222222/video/11111111",
"http://vimeo.com/album/2222222/video/11111111",
"https://vimeo.com/11111111?param=test",
"http://vimeo.com/11111111?param=test",
"http://vimeo.com/whatever/somethingelse/11111111?param=test",
"http://www.player.vimeo.com/stuff/otherstuff/11111111"
];
$.each(urls, function(index, url) {
var firstPart = url.split('?')[0].split("/");
var vid = firstPart[firstPart.length - 1];
$("table").append('<tr><td>'+url+'</td><td><span>'+vid+'</span></td></tr>');
});
td { font-family: monospace; }
span { background: lightgreen; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr><th>Input</th><th>Result</th></tr>
</table>
How it works :
url.split('?') breaks "http://vimeo.com/whatever/somethingelse/11111111?param=test" into ["http://vimeo.com/whatever/somethingelse/11111111","param=test"]
... or just ["http://vimeo.com/whatever/somethingelse/11111111"] if there is no ? in the URL.
Now [0] takes the first element of the array, which is "http://vimeo.com/whatever/somethingelse/11111111".
Then we split that using .split('/'), which gives ["http:","","vimeo.com","whatever","somethingelse","11111111"]
Now we just have to take the last element, which is our video ID :
vid = firstPart[firstPart.length - 1] // Gives "11111111"
Using your current code, just change your regex to this one:
/https?:\/\/player\.vimeo\.com\/video\/(\d+)/gm
And use the first (the unique) matched element $1.
If you only deal with vimeo urls, you can also observe and consider that the only integers in their urls give you the video id.
var noquery = url.replace(/\?.*/,'') // remove anything after a ?
var id = noquery.replace(/[^0-9]/g, '') // get all the digits
this would give you a simpler code until it breaks
it all depends if you want to extract the id from a url that you know is a video id or if you want to extract vimeo video urls among a bag of urls
Based on Jeremy Thille's answer in the list.
The last step, could we use pop() to get the last element from that array, which could be like this:
let videoId = url.split('?')[0].split('/').pop()

Regex split string and check if string is of type

Aanval op Vlemis (499|453) C44
This is what the string looks like. Though it's actually like this: "Aanval op variable (variable) variable
What I want to do is 1: get the coordinates (I already have this), 2 get Vlemis (first variable), get C44 (third variable) and check to see if the string is of this type.
My code:
$("#commands_table tr.nowrap").each(function(){
var text = $(this).find("input[id*='editInput']").val();
var attackername= text.match(/(?=op)[\s|\w]*(?=\()/);
var coordinates = text.match(/\(\d{1,3}\|\d{1,3}\)/);
});
Coordinates works, attackername however doesn't.
Html:
<span id="labelText[6]">Aanval op Vlemis (499|453) C44</span>
You should use one regex to take everything :
var parts = text.match(/(\w+)\s*\((\d+)\|(\d+)\)\s*(\w+)/).slice(1);
This builds
["Vlemis", "499", "453", "C44"]
If you're not sure the string is valid, test like this :
var parts = text.match(/(\w+)\s*\((\d+)\|(\d+)\)\s*(\w+)/);
if (parts) {
parts = parts.slice(1);
// do things with parts
} else {
// no match, yell at the user
}

Categories