I'm trying to check if the team contains one of the following strings in the array. If yes then remove it. Why is it not doing this?
function changeName(name) {
var team = name;
var removearray = ['.CS', ' Dota2', '-Dota2', ' Esports', 'eSports', ' Tactics', 'DotCom', ' DotA2', ' - LoL', '-LoL', ' Carry', 'Â', ' LoL'];
removearray.forEach(function( word ) {
team = team.replace( new RegExp( word, 'g' ), '' );
});
return team;
}
Please note that "forEach" is not supported in certain browsers such as IE8.
Also, please consider the following implementation:
function changeName(name) {
var removearray = ['.CS', ' Dota2', '-Dota2', ' Esports', 'eSports', ' Tactics', 'DotCom', ' DotA2', ' - LoL', '-LoL', ' Carry', 'Â', ' LoL'];
return team = removearray.reduce(function(previous, current) {
return previous.replace( new RegExp( current, 'g' ), '' );
}, name);
}
The "reduce" method available in the Array Prototype in Javascript is a very nice way of doing tasks such as this one.
function changeName(name) {
var team = name;
var removearray = ['.CS', ' Dota2', '-Dota2',
' Esports', 'eSports', ' Tactics', 'DotCom',
' DotA2', ' - LoL', '-LoL', ' Carry', 'Â', ' LoL'];
for(var i = 0; i < removearray.length; i++){
while(team.indexOf(removearray[i]) > -1) {
var index = team.indexOf(removearray[i]);
if (index > -1) {
team = team.substr(0, index) +
team.substr(index + removearray[i].length);
}
}
}
return team;
}
var one = changeName('John'); // returns 'John'
var two = changeName('John Dota2 Doe'); // returns 'John Doe'
var three = changeName('John Dota2 Doe Dota2.CS') // returns 'John Doe'
Related
I'm working with the Twitter API and I'm trying to get only the first news of a tweet and its link. If I console.log tweetNews I get something like this as example:
{
text: 'exampletext. \n' +
'\n' +
'exampletext. \n' +
'\n' +
'https://examplelink',
href: 'https://examplelink
},
I would like to get only the first string of the text, removing also the link inside the text.
Down below the rest of my code:
module.exports.filterTweets = (parsedArray) => {
const filteredTweets = parsedArray.filter(
(tweet) => tweet.entities.urls.length === 1
);
const tweetNews = filteredTweets.map((x) => {
return { text: x.full_text, href: x.entities.urls[0].url };
});
console.log("tweetNews", tweetNews);
return tweetNews;
};
I'm not sure I 100% follow what you are asking for, but this should get you on your way. This shows how to get the first part of the string (up to the first line break), and how to remove (http/https) URLs:
function cleanInput(input){
let firstLine = input.split(/\s+\n\s+/)[0]
//this regex is overly simplistic, just for demo purposes
//see more complete example at https://stackoverflow.com/a/3809435/57624
let withoutURL = firstLine.replace (/http[s]?:\/\/[a-z./]+/i, '');
return withoutURL
}
let sampleData1 = {
text: 'exampletext. \n' +
'\n' +
'exampletext. \n' +
'\n' +
'https://examplelink',
href: 'https://examplelink'
};
let sampleResult1 = cleanInput(sampleData1.text)
console.log("result 1: " + sampleResult1)
let sampleData2 = {
text: 'A URL: https://examplelink.com \n' +
'\n' +
'exampletext. \n' +
'\n' +
'more',
href: 'https://examplelink'
};
let sampleResult2 = cleanInput(sampleData2.text)
console.log("result 2: " + sampleResult2)
I am trying to filter an array with a text match with many elements. But my implementation only uses the first element to filter the array.
dataSource =
dataSource &&
dataSource.itemList.filter((result: any) =>
(
result.lotNumber ||
result.year ||
result.make ||
result.model ||
result.stockNumber ||
result.vin ||
result.mileageType ||
result.intColor ||
result.engine ||
result.crGrade ||
result.transmission ||
result.sellerName
)
.toLowerCase()
.includes(searchedText.toLowerCase())
);
In my solution, it only works for result.lotNumber. What seems to be the issue here?
Concat the values and do not use boolean operators.
dataSource =
dataSource &&
dataSource.itemList.filter((result: any) =>
(
'' +
result.lotNumber + ' ' +
result.year + ' ' +
result.make + ' ' +
result.model + ' ' +
result.stockNumber + ' ' +
result.vin + ' ' +
result.mileageType + ' ' +
result.intColor + ' ' +
result.engine + ' ' +
result.crGrade + ' ' +
result.transmission + ' ' +
result.sellerName
)
.toLowerCase()
.includes(searchedText.toLowerCase())
);
By using ||, the search is based on the first value not falsy.
You can add spaces to prevent that the concatenated values will match something by error.
Example:
If
result.model = 'V' and
result.stockNumber = '2'
By looking for 'V2', you'll have a match although it shouldn't. By adding spaces, you prevent that.
Enhancing the answer from sjahan, you can itterate the object keys of result without adding them one by one manually:
dataSource =
dataSource &&
dataSource.itemList.filter((result: any) =>
(Object.keys(result).map(key => result[key])).join(' ')
.toLowerCase()
.includes(searchedText.toLowerCase())
);
const itemList = [{
lotNumber: '123',
year: '2020',
make: 'doe',
model: 'model',
}, {
lotNumber: '456',
year: '2019',
make: 'jane',
model: 'othermodel',
}];
const result = (search) => itemList.filter((result) =>
(Object.keys(result).map(key => result[key])).join(' ')
.toLowerCase()
.includes(search.toLowerCase())
);
console.log(result('123'));
console.log(result('jane'));
I am using Angular. I currently am using ng-repeat to display my data from a rest endpoint. I want to have the name field not be the full name but rather - First Name - Last Initial. Example:
John Doe -> John D.
You need to write a method and use it in your project.
public customName (name) {
let newName = name.split(' ');
newName = newName[0] + ' ' + newName[1].slice(0, 1) + '.';
return newName;
}
Below is an example of how the code will work.
const customName = (name) => {
let newName = name.split(' ');
newName = newName[0] + ' ' + newName[1].slice(0, 1) + '.';
console.log(newName);
}
customName('John Doe');
this is simple, just with javascript
use charAt and split
var name_full = 'John Doe'
var name_array = name_full.split(' ');
name_array[0] + ' ' + name_array[1].charAt(0) + '.'; // "John D."
I want my context menu item to be visible only if the clicked node is a link i.e. and href is either a magnet link or a torrent link. But item is visible for all the links because context function is not executing, can anybody help why context function is not executing?
Here is the code:
exports.main = function() {
var cm = require("sdk/context-menu");
var contextCode = ' self.on("context", function (node) { '+
' while(node.nodeName!="A") { node = node.parentNode; } '+
' var pat_magnet = /^magnet:/i; ' +
' var pat_torrent = /.torrent$/i; ' +
' if(pat_torrent.test(node.href) || pat_magnet.test(node.href)) { return true; } '+
' else { return false; } '+
' }); ';
var clickCode = ' self.on("click", function(node,data){ '+
' while(node.nodeName!="A") { node = node.parentNode; } '+
' var pat_hash = /[0-9abcdef]{32,40}/i; ' +
' var result = node.href.match(pat_hash); '+
' var hash = "" '
' if(result != null) { hash=result[0]; } '+
' var xhr = new XMLHttpRequest(); '+
' if(hash != "") { '+
' var apiCall = "https://www.furk.net/api/dl/add?api_key=*************&info_hash="+hash; '+
' } '+
' else{ '+
' var apiCall = "https://www.furk.net/api/dl/add?api_key=*************&url="+encodeURI(node.href); '+
' } '+
' xhr.open("GET",apiCall,true); '+
' xhr.onreadystatechange = function(){ if(xhr.readyState = 4) { if (xhr.response.status = "ok") { alert("Torrent added to Furk."); } else { alert("Torrent could not be added to Furk."); } } } '+
' xhr.send(null); '+
' });';
cm.Item({
label: "Add to Furk",
context: cm.SelectorContext("a[href]"),
contentScript: contextCode + clickCode
});
};
Please always post self-containied examples that can be directly tried in the future.
Now back to your problem: The content script actually has a syntax error.
The following line:
' var pat_torrent = /.torrent$/i ' +
lacks a semicolon, and should be:
' var pat_torrent = /.torrent$/i; ' +
The reason automatic semicolon insertion (ASI) does not work here is: The "code" is actually a string that has no newlines in it whatsoever. If there were newlines, then ASI would have worked.
Anway, another reason not to have complex content script inline. Have a look at contentScriptFile.
This error is actually logged, but the presentation sucks. In the Browser Console:
[20:57:51.707] [object Error] (expandable)
In terminal:
console.error: context-magnet:
Message: SyntaxError: missing ; before statement
Here is a fixed, reproducible sample:
var cm = require("sdk/context-menu");
var contextCode = ' self.on("context", function (node) { '+
' while(node.nodeName!="A") { node = node.parentNode; } '+
' var pat_magnet = /^magnet:/i; ' +
' var pat_torrent = /.torrent$/i; ' +
' if(pat_torrent.test(node.href) || pat_magnet.test(node.href)) { return true; } '+
' else { return false; } '+
' }); ';
cm.Item({
label: "magnet test",
context: cm.SelectorContext("a[href]"),
contentScript: contextCode
});
Edit ' var hash = "" ' has the same problem, and there are might be other such errors that I missed skimming this new code.
As I already said, please use contentScriptFile and not contentScript for long-ish scripts.
Another edit
Here is a builder using contentScriptFile, where I also fixed a couple of other errors, the most important of which are:
Use permissions so that the XHR will work.
Correctly set up the XHR to use responseType and overrideMimeType().
Use onload/onerror instead of onreadystatechange.
Is this the optimal way to load form data into a string and then to localStorage ?
I came up with this on my own, and I am not good in programming. It works, for what I need, but I am not sure if it's a bulletproof code?
<script>
var sg = document.getElementById("selectedGateway");
var sd = document.getElementById("selectedDestination");
var dm = document.getElementById("departureMonth");
var dd = document.getElementById("departureDay");
var dy = document.getElementById("departureYear");
var rm = document.getElementById("returnMonth");
var rd = document.getElementById("returnDay");
var ry = document.getElementById("returnYear");
var ad = document.getElementById("adults");
var ch = document.getElementById("option2");
$("#searchRequestForm").submit(function() {
var string = 'From: ' + sg.value + ' \nTo: ' + sd.value + ' \nDeparture: ' + dm.value + '/' + dd.value + '/' + dy.value + ' \nReturn: ' + rm.value + '/' + rd.value + '/' + ry.value + ' \nNumber of adults: ' + ad.value + ' \nNumber of children: ' + ch.value;
localStorage.setItem("string", string);
});
</script>
I would use something like the following so that I could deal with an object and its properties rather than a big string. Note that other than the jQuery selectors, this is pure JavaScript.
Demo: http://jsfiddle.net/grTWc/1/
var data = {
sg: $("#selectedGateway").val(),
sd: $("#selectedDestination").val()
// items here
};
localStorage.setItem("mykey", JSON.stringify(data));
To retrieve the data:
var data = JSON.parse(localStorage["mykey"]);
alert(data.sg);
See Also:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/stringify
http://api.jquery.com/jQuery.parseJSON/
I prefer a table driven approach so there is no repeated code (DRY):
var ids = [
"selectedGateway", "From: ",
"selectedDestination", "\nTo :",
"departureMonth", "\nDeparture: ",
"departureDay", "/",
"departureYear", "/",
"returnMonth", " \nReturn: ",
"returnDay", "/",
"returnYear", "/",
"adults", " \nNumber of adults: ",
"option2", " \nNumber of children: "];
var submitStr = "";
for (var i = 0; i < ids.length; i+=2) {
submitStr += ids[i+1] + document.getElementById(ids[i]).value;
}
localStorage.setItem("string", submitStr);
You could define a function such as the one below to directly get the values by id so then it would be simpler when you build your string.
function form(id) {
return document.getElementById(id).value;
}