Test if a value exists in a map in a ng-if - angularjs

How can I test if a value exists in a map in a ng-if?
$scope.textInputTypes = {
"currency": true,
"double": true,
"percent": true,
"int": true,
"email": true,
"phone": true,
"string": true,
"textarea": true,
"url": true
};
ng-if='mytype in textInputTypes'
This gives me an error:
Syntax Error: Token 'in' is an unexpected token at column 17 of the
expression [mytypeNaNn textInputTypes] starting at [in
textInputTypes].

You can also do the following:
<element ng-if='textInputTypes.hasOwnProperty(mytype)'>
Just keep in mind that the content inside the element won't be part of the DOM if the IF condition is not met, if you still want the content to exist you can also use ng-show

Finally, I found a way to do it.
ng-if="textInputTypes[myType]"

Related

Azure Cognitive Search Complex object filtering

I have an index with azure cognative search but cant seem to find the right syntax to query it for what I need.
I have documents that looks like the below and want to be able to pass in a search for "black denim shirt" and have that matched against each item object in the document rather than the whole document.
I need this match to be confined to the objects as I don't want the "black" and "denim" from the "black denim shirt" query to be matched to a "black denim jeans". Therefore the match/higher ranked result should be Document 2
Document 1:
{
"id": "Style1",
"itemKeyWords": [
{
"productKeyWords": "shirt,oversized shirt,denim",
"attributeKeyWords": "blue"
},
{
"productKeyWords": "Skinny, denim, jeans",
"attributeKeyWords": "black"
}
]
}
Document 2:
{
"id": "Style2",
"itemKeyWords": [
{
"productKeyWords": "shirt,oversized shirt,denim",
"attributeKeyWords": "black"
},
{
"productKeyWords": "Skinny, denim, jeans",
"attributeKeyWords": "blue"
}
]
}
I have the itemKeyWords set up in the index as a
{
"name": "itemKeyWords",
"type": "Collection(Edm.ComplexType)",
"fields": [
{
"name": "productKeyWords",
"type": "Edm.String",
"searchable": true,
"filterable": true,
"retrievable": true,
"sortable": false,
"facetable": true,
"key": false,
"indexAnalyzer": null,
"searchAnalyzer": null,
"analyzer": "en.lucene",
"normalizer": null,
"synonymMaps": []
},
{
"name": "attributeKeyWords",
"type": "Edm.String",
"searchable": true,
"filterable": true,
"retrievable": true,
"sortable": false,
"facetable": true,
"key": false,
"indexAnalyzer": null,
"searchAnalyzer": null,
"analyzer": "en.lucene",
"normalizer": null,
"synonymMaps": []
}
]
}
I have tried various attempts using this as a guid but cant seem to get the syntax right
https://learn.microsoft.com/en-gb/azure/search/search-howto-complex-data-types?tabs=portal
Unfortunately, as of today, it is not possible to make "search" requests (queries that rely on the tokenized content) that enforce the requirement to have all matches within a specific entry of a complex object collection. This is only supported for filters right now (as long as the filter does not rely on the search.in function).
I can think of two (less than idea) work around:
Index each entry of the collection as separate documents
Flatten the sub-fields into a single field:
AggregateField: "Skinny, denim, jeans. black"
And then emit a query that use proximity search (to make sure all terms are within a certain distance):
queryType=full&search="black denim jeans"~5
If it's important for you to still keep the structured version of the content in the document (attribute and keywords separately), you can still index them along side the aggregated field for retrieval purpose (you can target different fields for matching purpose vs the one you actually return in the response by using select and searchFields)
queryType=full&search="black denim jeans"~3&searchFields=aggregatedFields&select=productKeyWords, attributeKeyWords
or
queryType=full&search=aggregatedFields:"black denim jeans"~3&select=productKeyWords,attributeKeyWords

Azure search services issue for white space and wildcard search of special characters

We have an application that allows the users to enter anything on the summary field. The users can type in any special characters like #$!#~ etc including white space and they request that they can search based on those special characters as well. For example, one of the entry is "test testing **** #### !!!!! ???? # $".
I created a cognitive search index with analyzer to be standard.lucene, shown below:
{
"name": "Summary",
"type": "Edm.String",
"searchable": true,
"filterable": true,
"retrievable": true,
"sortable": true,
"facetable": true,
"key": false,
"indexAnalyzer": null,
"searchAnalyzer": null,
"analyzer": "standard.lucene",
"synonymMaps": []
}
When I used the postman query:
{ "top":"1000",
"queryType": "full",
"searchMode":"all",
"search": "testing",
"searchFields": "Summary",
"count":true
}
I can get the expected result.
If I use the following:
{ "top":"1000",
"queryType": "full",
"searchMode":"all",
"search": "testing ****",
"searchFields": "Summary",
"count":true
}
I got the error with "InvalidRequestParameter".
If I changed to the following query:
{ "top":"1000",
"queryType": "full",
"searchMode":"all",
"search": ""****"",
"searchFields": "Summary",
"count":true
}
Then I am not getting any results back.
Per this article:
https://learn.microsoft.com/en-us/azure/search/query-lucene-syntax#escaping-special-characters
In order to use any of the search operators as part of the search text, escape the character by prefixing it with a single backslash ().
Special characters that require escaping include the following:
& | ! ( ) { } [ ] ^ " ~ * ? : \ /
I need to prefix with single backslash for the special characters. But in my case it doesn't seem to work. Any help will be appreciated!
If you are using standard lucene analyzer for your indexing, I believe the "****" is not saved as a word. Lucene analyzer breaks the words on special characters.
For fields that you need to be searched on, e.g., the summary field in your example, you need to create a custom analyzer for that field. This document talks about how you can do that, test your analyzer. Once you have built an analyzer that tokenizes the input the way you want, you can use that in your index definition for the fields that need it as follows.
...
{
"name": "Summary",
"type": "Edm.String",
"retrievable": true,
"searchable": true,
"analyzer": "custom_analyzer_for_tokenizing_as_is"
},
...
I finally get this one resolved by creating a customized analyzer. The index definition:
{
"name": "FieldName",
"type": "Edm.String",
"searchable": true,
"filterable": true,
"retrievable": true,
"sortable": true,
"facetable": true,
"key": false,
"indexAnalyzer": null,
"searchAnalyzer": null,
"analyzer": "specialcharanalyzer",
"synonymMaps": []
},
The analyzer is specified below:
"analyzers": [
{
"#odata.type": "#Microsoft.Azure.Search.CustomAnalyzer",
"name": "specialcharanalyzer",
"tokenizer": "whitespace",
"tokenFilters": [
"lowercase"
],
"charFilters": []
}
],
Then you can use the format this document specified https://learn.microsoft.com/en-us/azure/search/query-lucene-syntax#special-characters
https://learn.microsoft.com/en-us/azure/search/query-lucene-syntax#special-characters
Special characters that require escaping include the following:
+ - & | ! ( ) { } [ ] ^ " ~ * ? : \ /
For characters not in the above required escaping character, use the following format for infix search:
"search": "/.*SearchChar.*/",
For example, if you want to search for $, then use the following format:
"search": "/.*$.*/",
For special characters in the list, use this format:
"search" : "/.*\\escapingcharacter.*/",
For example to search for +, use the following query;
"search" : "/.*\\+.*/",
# is also considered to be escaping character if it is in a statement.
To search for *, use this format:
"search":"/\\**/",

Possibly broken azure-search tokenizer - PathHierarchyTokenizerV2

Lately, I wanted to take advantage of a field on my search index that uses a custom analyzer with the PathHierarchyTokenizerV2 tokenizer.
this same index used to work, and the custom analyzer did break the text into the correct path segments when using the "Analyzer Test" API.
i.e. the text l1/l2/l3 turns into:
l1,
l1/l2,
l1/l2/l3,
At the moment, it seems like this functionality no longer works. Or, am I doing something wrong?
I reproduce by creating an index with the following field:
{
"name": "tags",
"type": "Edm.String",
"searchable": true,
"filterable": true,
"retrievable": true,
"sortable": false,
"facetable": true,
"key": false,
"indexAnalyzer": null,
"searchAnalyzer": null,
"analyzer": "categoryPathAnalyzer",
"synonymMaps": []
}
Where categoryPathAnalyzer is defined as:
{
"#odata.type": "#Microsoft.Azure.Search.CustomAnalyzer",
"name": "categoryPathAnalyzer",
"tokenizer": "path_hierarchy_v2",
"tokenFilters": [
"lowercase"
],
"charFilters": []
}
The "Analyzer Test" API is called with the following body:
{
"text": "a/b",
"analyzer": "categoryPathAnalyzer"
}
And the result is empty:
{
"#odata.context": "https://x.search.windows.net/$metadata#Microsoft.Azure.Search.V2016_09_01_Preview.AnalyzeResult",
"tokens": []
}
If it matters, this index and calls are all using the latest 2016-09-01-Preview API version.
Thanks for reporting this. We found a bug in the built-in path_hierarchy_v2 tokenizer. The bug has been fixed. Please let us know if the issue persists.

Set criteria in query for fields and fields in nested objects

I have a document like this:
{
"InDate": "11.09.2015",
"Kst2Kst": true,
"OutDate": "11.09.2015",
"__v": 0,
"_id": ObjectId('55f2df2d7e12a9f1f52837e6'),
"accepted": true,
"inventar": [
{
"accepted": "1",
"name": "AAAA",
"isstammkost": true,
"stammkost": "IWXI"
},
{
"accepted": "1",
"name": "BBBB",
"isstammkost": false,
"stammkost": "null"
}
]
}
I want to select the data with "isstammkost": true in the inventar-array.
My query is:
Move.findOne({accepted : true, 'inventar.isstammkost' : true},
'OutDate InDate inventar.name', function(err, res)
It doesn't work -> It selects all, even with inventar.isstammkost : false.
The "normal" query works like I want (without criteria in sub-array). Whats the right way to set criteria in sub-array?
Of course it will return the "isstammkost": false part, because that is part of the same document as the "isstammkost": true. They are both objects in the array "inventar", a top-level field in a single document. Without some sort of projection, the entire document will always be returned to a mongodb query and thus nodejs will pass them on to you.
I'm not terribly up-to-speed on nodejs, but if this were the mongo shell it would look like this:
> db.MyDB.findOne({{accepted : true, "inventar.isstammkost" : true}, {"inventar.isstammkost.$": 1});
You will need to find out how to add that extra parameter to the nodejs function.

Errors without name in AngularJS form

I'm trying to disable a button if the form in which it is in isn't valid. However, for some reason the $error array associated with the form is holding a list of ten useless errors (so the button is always off), all with the following shape:
{
"$validators": {},
"$asyncValidators": {},
"$parsers": [],
"$formatters": [
null
],
"$viewChangeListeners": [],
"$untouched": true,
"$touched": false,
"$pristine": true,
"$dirty": false,
"$valid": false,
"$invalid": true,
"$error": {
"required": true
},
"$name": "",
"$options": null
}
As you can see, with an empty $name property, and with no other helpful information.
I've found a solution, although not to the originally posted problem. The issue was that I was using ngIf to hide some parts of the form, containing inputs, intentionally. But at some point the magic idea of changing this to ngShow came to my mind, and I just didn't realize the consequences until some time after. So there was the problem, Angular considers the hidden elements but not the non-existing ones for form validation. It sounds logic and reasonable.
But, this was the first time I started to debug the form properties in this application, and have no idea about why the $name's are empty. Could it be that I'm using the "controller as" syntax instead of attaching the stuff to the $scope? Maybe is because of this, but anyway I think this is a downside of Angular somehow.

Resources