How to check if array includes string in PUG template - javascript

I am using NodeJS with Express and the PUG view engine.
I am attempting to check if an array contains a certain string. I have tried the builtin javascript methods such as:
array.includes(str)
array.indexOf(str) > -1.
However neither of these options seem to work. How can I check if an array contains a certain string in PUG?
if example_array.length > 0
span() Array contains elements! // This works and appears on page
if example_array.includes('example string') // This does not work
span() Array includes example string! // This does not appear on page

If you want to run inline JS in your template you have to mark your code as unbuffered.
https://pugjs.org/language/code.html#unbuffered-code
if example_array.length > 0
span() Array contains elements!
- if (example_array.includes('example string'))
span() Array includes example string!
Note the "-" in front of the "if" on line 3.
Since this is a literal js expression now the parantheses are required aswell.

This kept me busy for hours so I wanted to share my own solution. While the answer is correct when checking for a string directly, remember you may need to add .toString() if you're checking from a variable:
- if (example_array.includes(myVariable.toString()))
Hopefully this saves someone some time!

Related

TypeError: Cannot call method "indexOf" of null

I'm triying to find the records that includes "SO -" or "NS - SO" or "SO –" or "SWAT" on THE "RESUMEN" field from a CSV file to asigne a new category (in this cases would be "Call Center"). So, I used "indexOf" funtion witch worked so well.
The problem comes when I change the data source (It is a CSV too), this gave me next error on that step:
"Caused by: org.mozilla.javascript.EcmaError: TypeError: Cannot call method "indexOf" of null (script#2)"
The objective is to assign a category by identifying the words on the source file
My code
if (RESUMEN.indexOf("SO -")!=-1 || RESUMEN.indexOf("NS - SO")!=-1 || RESUMEN.indexOf("SO –" )!=-1 || RESUMEN.indexOf("SWAT")!=-1)
{
var RESULTADO = "Call Center"
}
else RESULTADO = ""
I expect to assigne call center category like I got with the first file (I did not change nothing)
regards!
You're overcomplicating the issue.
Before the answer, remember something, there are several steps, and combinations of steps, that achieve an incredible number of transformations to make usable patterns, the last resort IS User defined Java Expression.
Seems like what you want to achieve is a Value Mapping, thou the difference from a direct value map in your case, is that the row you're testing must contain "SO -", and the other cases, somewhere in the text.
With this simple filter, you can transform your data that contains those informations as you desire, and on the "FALSE" side, treat it for errors.
This will expand your transformation a bit, but when you need to change something it will be easier than with a single step with a lot of code.
As another answer pointed out, you can achieve the same result with different steps, you don't need the javascript step.
But, if you want to go that route, you should first convert null values into, e.g., empty strings.
Simply add this to the beginning of your javascript code:
if (!RESUMEN){ RESUMEN = ''}
That'll convert nulls to empty strings and then indexOf returns correctly.

Sort an HTML List Based on a String

I have a list of files displayed on my webpage that are organized in order of the date they were created. The file names display in the following format.
file_1_abc_10-23-2015.txt
file_2_fff_10-25-2015.txt
file_88_xyz_11-15-2015.txt
file_42_abc_11-17-2015.txt
file_9_ttt_11-25-2015.txt
I want to organize them based on a phrase they contain - in this case I want to sort by the third string phrase in the file name, so the sorted list would look like this
file_1_abc_10-23-2015.txt
file_42_abc_11-17-2015.txt
file_2_fff_10-25-2015.txt
file_9_ttt_11-25-2015.txt
file_88_xyz_11-15-2015.txt
//abc > abc > fff > ttt > xyz
I'm not sure whether this should be tackled with a front end script like jquery, or if this can be accomplished with a templating engine (I'm using thymeleaf, but I don't want to taylor this as a thymeleaf question because the output list is just basic HTML). I've just begun with this task and don't want to overkill it - Any thoughts?
Thanks much
Assuming the list of files is an array, you can do this:
fileNames.sort(function(a, b){
return a.split('_')[2].localeCompare(b.split('_')[2]);
});
Note that you don't need to assign the return value of sort to the array, since sort works in place. It changes the variable itself.
.split('_')[2] splits the string up into an array: ['file', '1', 'abc', '10-23-2015.txt'], then returns the value at index 2, which is 'abc', this is then used in the sort.

jQuery/JavaScript regex return matched text from string

I am trying to create a fairly complex system for my website. I want to be able to write some pseudo like code and then parse it to make it do something in my back-end.
My data is inside two $.each loops as this is an Object of data with multiple levels to it.
For instance, I want to take a string like this:
"<!this!> == <!PropertyStreetNumber!>"
Then how I would like for the above code to executed is this:
FormData[parentKey][this] == FormData[parentKey]["PropertyStreetNumber"]
Thanks for any help!
Here's some of my code, the code where this would need to go in (see commented area)
http://jsbin.com/liquvetapibu/1/
Is there any restriction not to use regular expressions on JavaScript?
You could do something like this:
var myString = "<!this!> == <!PropertyStreetNumber!>";
var aux = /<!(.*?)!> == <!(.*?)!>/.exec(myString);
The value of aux will be an array with 3 elements:
The string that was tested.
The first element within <! !>
The second element within <! !>
Then it would depend on what the content on each one is: in your example this is an object, while you seem to use PropertyStreetNumber as a string (maybe a typo?). If you want to use it as an object, you will have to use eval() (e.g.: eval(aux[1])) while if you want to use it as a string, you can use it directly (e.g.: aux[2]).
Conceptually, the first thing you would need to do is determine the type of statement you are working with. In this case, a comparison statement. So you need a regex statement to filter this into a "statement type".
Once you do that, you can figure out what the arguments are. So you create a regex to pull out the arguments on each side of the operator.
Next, the strings that represent action code items need to be parsed. The this argument is actually an object, whereas "PropertyStreetNumber" is a string. You've got to be able to determine which is which. Then you can filter that into a function that has been created specifically to handle those statements types.
If at all possible, I would try to avoid the use of eval(). You can get into trouble with it.
you could try with
var beg = str.indexOf("== <!") + 5;
to find the index of the beggining and then slice counting the chars from beginning like
str.slice(beg, -2);
and from there build the rest.
couldnt that work?`

Significance of ".$" when appended to an AngularJS filter object

I am trying to understand a section of code pertaining to filtering in AngularJS that I found on the documentation website. (cf. http://docs.angularjs.org/api/ng.filter:filter)
In particular, the .$ appended to the object search, which is used in the following lines:
24. Any: <input ng-model="search.$"> <br>
25. Name only <input ng-model="search.name"><br>
26. Phone only <input ng-model="search.phone"><br>
...
30. <tr ng-repeat="friendObj in friends | filter:search:strict">
Using a JSFiddle to hack around, I tried removing the .$ and then typing text in the input field to apply filtering. This worked fine. So, in general, why should I even bother appending .$ if the search filter can work without it?
I am quite new to AngularJS (as well as JS I suppose) and have been enjoying learning it so far. Any help will be much appreciated.
If you read the filter page, you will notice this line:
That's equivalent to the simple substring match with a string as described above.
So basically it is saying that when you put just ng-model="search", you are using a string search, which by default searches all string items within the array/object. When you use search.$, you are specifying that you want to search each item within an object. As the sentence explains, these are equivalent.
While just search achieves the same result with less code, I believe .$ better explains the intentions of the filter in the example.
It works to search on all properties of the objects. In case of search.name you search only for objects where the name property matches, but search.$ searches on all properties.
A special property name $ can be used (as in {$:"text"}) to accept a match against any property of the object. That's equivalent to the simple substring match with a string as described above.
From http://docs.angularjs.org/api/ng.filter:filter

Split to get the text between separators?

I am making a cross domain AJAX request, and because of this, I can't pass the original array from the PHP page to my HTML page. Instead, the request gets the results as a string. I have it set up so that the syntax looks like this:
([SCHOOL] Name [/SCHOOL][STATUS] Status [/STATUS])
([SCHOOL] Other name [/SCHOOL][STATUS] Other status [/STATUS])
On my HTML page, I want to be able to form an array from these different values, in the form of:
Array (
[0] =>
[0] Name
[1] Other
[1] =>
[0] Name
[1] Other status
)
This way, I can use a for loop to get specific values.
The only problem with is that split only does just that, splits things. Is there a way in JS to find the text within separators, and form an array from it? In the example again, it'd find all text within the parenthesis, and form the first array, then within that array, use the text between [SCHOOL][/SCHOOL] for the first object, and use the text between [STATUS][/STATUS] for the second object.
Ideally, you would use something more suited to storing arrays on the server side. I would recommend JSON. This would be trivial to encode using php, and decode using javascript.
If you do not have that option server side, then you can use regex to parse your text. However, you must be sure that the contents does not have your delimiters within in it.
It is not clear how you get your target data structure from your source, but I would expect something like this might work for you:
str = "([SCHOOL] Name [/SCHOOL][STATUS] Status [/STATUS])\n\
([SCHOOL] Other name [/SCHOOL][STATUS] Other status [/STATUS])"
arr =[]
m = str.match(/\(.+?\)/g)
for(i in m){
matches = m[i].match(/\(\[SCHOOL\](.+?)\[\/SCHOOL\]\[STATUS\](.+?)\[\/STATUS\]\)/)
arr.push([matches[1],matches[2]])
}
console.dir(arr)

Categories