Multiple APIs are called with (change) in angular - html

On selecting any date and hitting enter an API call should be made. And there's a x icon in the input on clicking it, it should call the API with date 01/01/12 Also this has feature like if you type 2/3 and hit enter it will automatically make it 02/03/20. The problem is if the input is empty and if I hit Enter same API calls are made thrice.
But the feature should be like if you select a date then without hitting Enter an API call should be made. I can't just use change function because if 2/3 is typed and Tab is pressed then it will not adjust the date automatically and also multiple API calls on hitting Enter. Is there a way to stop multiple API calls?
(change)="startDate($event)" (keydown.enter)="CallAPI($event)"
startDate(event) {
if (event.target.value == '' || event.target.value == null)
this.cutoverFilterApi(event)
}
CallAPI(event) {
let data = event.target.value;
if (data != '' && data != null && data != "NaN/NaN/NaN") {
data = data;
} else {
data = "01/01/12";
}
this.httpService.getData('PATH' + data).subscribe((response: any) => {
this.dateChangeData = response.results;
this.rowData = response.results;
this.gridApi.setRowData(this.rowData);
});
}

You could keep the last valid value and avoid request if it is the same.
Something like this,
lastDate = null; // <- variable to keep last value
CallAPI(event) {
let data = event.target.value;
if (data != '' && data != null && data != "NaN/NaN/NaN") {
data = data;
} else {
data = "01/01/12";
}
// check if data is not the same as last request
if (this.lastDate === data) {
return;
}
this.lastDate = data; // <- update new request date
this.httpService.getData('PATH' + data).subscribe((response: any) => {
this.dateChangeData = response.results;
this.rowData = response.results;
this.gridApi.setRowData(this.rowData);
});
}

You can use this
(dateInput)="addEvent('input', $event)" (dateChange)="addEvent('change', $event)"
instead of
(change)="startDate($event)" (keydown.enter)="CallAPI($event)"
I have an example of angular material datepicker, which will make your code easier.
Reference link
I hope it is helpful for you. :)

Related

AngularJS Selects Empty Option Even Valid Option is Avaliable

I'm using AngularJS ver. 1.2.15 on my project. And, I have a select element on one of my views as per below:
<select class="select-white form-control form-select" id="cat2_{{feed.id}}" ng-model="feed.operationstatusid" ng-change="updateCategoryAndStatus(feed, true)"></select>
And, I'm feeding this element like this:
function SetCategory2(cat1Id, feed) {
var feedId = feed.id;
var fromRuleOpStatusId = -1;
$('#cat2_' + feedId).find('option').remove();
if (cat1Id > -1) {
$('#cat2_' + feedId).append($('<option></option>').text(lang.SelectSubCategory).val(0));
$.each($scope.category2, function (index, cat2Item) {
$('#cat2_' + feedId).append($('<option></option>').text(cat2Item.statusdescription).val(cat2Item.id));
});
var isselected = false;
$.each($scope.category2, function (index, cat2Item) {
if (feed.operationstatusid == cat2Item.id) {
$('#cat2_' + feedId).val(cat2Item.id);
fromRuleOpStatusId = -1;
isselected = true;
}
else {
var feedStr = "";
if (feed.title != undefined && feed.title != null) {
feedStr = feed.title.toLowerCase();
}
if ($scope.catTitleRulesTwo) {
$.each($scope.catTitleRulesTwo, function (r_index, r_item) {
if (cat2Item.id == r_item.titleCode && !isselected) {
if (feedStr != undefined && feedStr != null && r_item != undefined && r_item != null) {
String.prototype.contains = function (str) { return this.toLowerCase().indexOf(str) !== -1; };
var text = feedStr;
if (eval(r_item.ruleexpression)) {
$('#cat2_' + feedId).val(cat2Item.id);
fromRuleOpStatusId = cat2Item.id;
isselected = true;
}
}
}
});
}
}
});
if (fromRuleOpStatusId != -1) {
feed.operationstatusid = fromRuleOpStatusId;
}
}
else {
$('#cat2_' + feedId).append($('<option></option>').text(lang.SelectSubCategory).val(0));
}
}
I am aware of the facts about eval function, but the project I'm working on is quite old, so does the code. Anyway, this is about business logic and quite irrelevant with the thing I'm going to ask (or so I was thinking).
As you can see I'm appending all the options before I set the value of the selectbox with using .val(...). I have also checked that values do match along with the data types. But, when I observe this function step by step, I saw that selected value does show up without flaw. After the code finish with my above mentioned function (SetCategory2), code goes through on of the function located on AngularJS file, named xhr.onreadystatechange. It's not a long function, so I'm sharing it also on below.
xhr.onreadystatechange = function() {
if (xhr && xhr.readyState == 4) {
var responseHeaders = null,
response = null;
if(status !== ABORTED) {
responseHeaders = xhr.getAllResponseHeaders();
response = ('response' in xhr) ? xhr.response : xhr.responseText;
}
completeRequest(callback,
status || xhr.status,
response,
responseHeaders);
}
};
After the code released from this function, respective selectbox's value is pointed at the empty option.
I have run into topics which talks about this behaviour might due to invalid option-value match, but as I described above, I append all my options before deciding the value. So, I can't figure out what I'm missing.
Thank you in advance.

Can I use duplicate IDs on multiple <template> fragments?

Why does HTML5 validation fail when having duplicate element IDs but on different <template>. I'm planning to use only one template at a time so the actual DOM ID won't be duplicated.
something like:
<template id="companyAccount">
<li><label>Company: <input type="text" id="account_name"></label></li>
<li><label>Street: <input id="account_street" ...
...
</template>
<template id="residentialAccount">
<li><label>Name: <input type="text" id="account_name"></label></li>
<li><label>Street: <input id="account_street" ...
...
</template>
<script>
...
let template = $(isResidential ? '#residentialAccount' : '#companyAccount').get(0).content;
$('#account_info').empty().append(template.cloneNode(true));
</script>
As TJBlackman mentioned each value for id attributes must be unique. However when working with code it's up to you to determine if the code being imported contains a duplicate id. Additionally I've pretty much stopped using validators for the most part as they aren't well maintained (and the W3C's CSS validator is atrocious) and the consoles, proper error handling and using the XML parser for HTML5 will tell you pretty much everything you need to know.
You have a couple of options. You can use data-account="residential" (don't make the mistake of using camelCasing as that will eventually put you in direct conflict with the standards bodies) and detect the attribute via document.querySelectorAll:
function $(o)
{
var a = true;
try {document.querySelectorAll(o);}
catch(err) {a = false; console.log('Error: "'+o+'" is not a valid CSS selector.'); sound.notice();}
return (a && document.querySelectorAll && document.querySelectorAll(o)) ? document.querySelectorAll(o) : false;
}
Usage: $('[data-account="residential"]')[0].length and $('[data-account="residential"]')[0].value.
Alternatively you can do what I do with my platform which has things tightly integrated though this is the function I use that you might decide to slim down for your specific purposes. You can use document.createTreeWalker and literally go through every single element to scan for walker.currentNode.hasAttribute('id') to test against document.getElementById. This code is used before importing XML in to the DOM on my platform:
/******** part of larger ajax() function ********/
if (xhr.readyState == 4 && xhr.status != 204)
{}
//This code occurs within the above condition.
var r = jax_id_duplication_prevention(xhr.responseXML,param_id_container_pos,id_container);
if (r)
{
if (param_id_container_pos=='after') {id_container.parentNode.insertBefore(xml.getElementsByTagName('*')[0],id_container.nextSibling);}
else if (param_id_container_pos=='before') {id_container.parentNode.insertBefore(document.importNode(xml.getElementsByTagName('*')[0],true),id_container);}
else if (param_id_container_pos=='first')
{
if (id_container.childNodes.length > 0) {id_container.insertBefore(document.importNode(xml.getElementsByTagName('*')[0],true),id_container.firstChild);}
else {id_container.appendChild(document.importNode(xml.getElementsByTagName('*')[0],true));}
}
else if (param_id_container_pos=='inside') {id_container.appendChild(document.importNode(xml.getElementsByTagName('*')[0],true));}
else if (param_id_container_pos=='replace') {id_container.parentNode.replaceChild(document.importNode(xml.getElementsByTagName('*')[0],true),id_container);}
else if (param_id_container_pos=='fragment')
{
if (option.fragment) {delete option.fragment;}
option.fragment = document.importNode(new DOMParser().parseFromString(xhr.responseText,'application/xml').childNodes[0],true);
if (id_container && typeof id_container == 'function') {id_container();}
}
else {alert('Error: unknown position to import data to: '+id_container_pos);}
}
/******** part of larger ajax() function ********/
function ajax_id_duplication_prevention(xml,param_id_container_pos,id_container)
{
var re = true;
if (typeof id_container == 'string' && id_container.length > 0 && id_(id_container)) {id_container = id_(id_container);}
if (typeof option.id_fade == 'string' && option.id_fade.length > 0 && id_(option.id_fade)) {element_del(option.id_fade); option.id_fade = '';}
if (typeof xml.firstChild.hasAttribute == 'function')
{
if (xml.firstChild.hasAttribute('id') && xml.firstChild.getAttribute('id').length > 0 && id_(xml.firstChild.getAttribute('id')) && id_(xml.firstChild.id).parentNode.id=='liquid') {change(xml.firstChild.id,'fade');}
if (xml.firstChild.hasAttribute('id') && xml.firstChild.getAttribute('id').length > 0 && id_(xml.firstChild.id) && !id_(xml.firstChild.id).parentNode.id=='liquid') {re = false;}
else if (typeof document.createTreeWalker=='function')
{
var idz = [];
try
{
var walker = document.createTreeWalker(xml,NodeFilter.SHOW_ELEMENT,null,false);
while (walker.nextNode())
{
if (walker.currentNode.hasAttribute('id') && walker.currentNode.getAttribute('id').length > 0)
{
if (walker.currentNode.id==undefined && walker.currentNode.nodeName.toLowerCase()=='parsererror') {console.log('Error: a parser error was detected.');}
else if (walker.currentNode.id==undefined) {alert('walker.currentNode.nodeName = '+walker.currentNode.nodeName+'\n\n'+document.serializeToString(xml));}
else
{
for (var i = 0; i<id_('liquid').childNodes.length; i++)
{
if (id_('liquid').childNodes[i].nodeType==1 && id_(walker.currentNode.id) && is_node_parent(walker.currentNode.id,id_('liquid').childNodes[i]) && (param_id_container_pos!='replace' || walker.currentNode.id!=id_container.id))
{
if (param_id_container_pos != 'replace' && id_container != walker.currentNode.id) {element_del(id_('liquid').childNodes[i]);}//If changing operator test: ajax('get','?ajax=1&web3_url=/'+url_section()+'/'+url_page(),'replace',push_current_id());
}
}
var n = id_(walker.currentNode.id);
if (in_array(walker.currentNode.id,idz))
{
var fd = new FormData();
fd.append('ajax','error_xml');
fd.append('post_error','Duplicate id <code>'+walker.currentNode.id+'</code>.');
fd.append('post_url',url_window().split(url_base())[1].split('?')[0]);
fd.append('post_xml',new XMLSerializer().serializeToString(xml));
if (fd) {ajax('post',path+'/themes/',fd);}
modal.alert('Error: can not import XML, the id \''+walker.currentNode.id+'\' was detected twice in the layer being imported. Duplicated ID\'s break expected functionality and are illegal. While the XML content was not imported it is still possible that the related request was successful. It is possible to override this problem by simply doing a full request (press the Go button in your browser\'s graphic user interface) however if the id is referenced programmatically the website may exhibit unusual behavior.');
break;
setTimeout(function()
{
history.back();
push_reload();
console.log('Developer: duplicate id '+walker.currentNode.id+' was encounterted.');
if (status >= 9) {modal.xml('Duplicate ID Error', '%3Cp%3EError%3A%20the%20id%20%3Ccode%3E'+walker.currentNode.id+'%3C%2Fcode%3E%20occurred%20twice%20and%20therefore%20the%20page%20can%20not%20be%20viewed.%3C%2Fp%3E%3Cp%3EFor%20debugging%20and%20fixing%20purposes%20you%20should%20consider%20opening%20the%20URL%20in%20a%20new%20tab.%3C%2Fp%3E%3Cdiv%20class%3D%22center%20margin%22%3E%3Cinput%20onclick%3D%22modal.close()%3B%22%20tabindex%3D%223%22%20type%3D%22button%22%20value%3D%22Close%22%20%2F%3E%3C%2Fdiv%3E');}
else {modal.xml('Duplicate ID Error', '%3Cp%3EError%3A%20the%20id%20%3Ccode%3E'+walker.currentNode.id+'%3C%2Fcode%3E%20occurred%20twice%20and%20therefore%20the%20page%20can%20not%20be%20viewed.%3C%2Fp%3E%3Cdiv%20class%3D%22center%20margin%22%3E%3Cinput%20onclick%3D%22modal.close()%3B%22%20tabindex%3D%223%22%20type%3D%22button%22%20value%3D%22Close%22%20%2F%3E%3C%2Fdiv%3E');}
re = false;
},4000);
}
else {idz.push(walker.currentNode.id);}
}
if (id_(walker.currentNode.id) && (param_id_container_pos!='replace' && walker.currentNode.id!=id_container.id && !is_node_parent(walker.currentNode.id,id_container)))
{//ajax replace (carousel loader) complications if changed.
re = false;
modal.alert('Error: unable to import page, the id \''+walker.currentNode.id+'\' already exists in the DOM.');
break;
}
}
}
}
catch (err) {}//IE9
}
}
return re;
}
Regardless of how you approach addressing the issue it is not one addressed by the standards bodies and must be explicitly handled by developers. Failure to handle duplicate id attribute/values will result in the wrong element being chosen at some point which may quietly accrue compromised/malformed data over time that no one might notice for years and thus could easily hinder if not outright destroy any business relations effected by it. Good luck!

Assign JSON value to variable based on value of a different key

I have this function for extracting the timestamp from two JSON objects:
lineReader.on('line', function (line) {
var obj = JSON.parse(line);
if(obj.Event == "SparkListenerApplicationStart" || obj.Event == "SparkListenerApplicationEnd") {
console.log('Line from file:', obj.Timestamp);
}
});
The JSON comes from a log file(not JSON) where each line represents an entry in the log and each line also happens to be in JSON format on its own.
The two objects represent the start and finish of a job. These can be identified by the event key(SparkListenerApplicationStart and SparkListenerApplicationEnd). They also both contain a timestamp key. I want to subtract the end time from the start time to get the duration.
My thinking is to assign the timestamp from the JSON where Event key = SparkListenerApplicationStart to one variable and assign the timestamp from the JSON where Event key = SparkListenerApplicationEnd to another variable and subtract one from the other. How can I do this? I know I can't simply do anything like:
var startTime = if(obj.Event == "SparkListenerApplicationStart"){
return obj.Timestamp;
}
I'm not sure if I understood, but if are reading rows and want get the Timestamp of each row I would re-write a new object;
const collection = []
lineReader.on('line', function (line) {
var obj = JSON.parse(line);
if(obj.Event == "SparkListenerApplicationStart" || obj.Event == "SparkListenerApplicationEnd") {
// console.log('Line from file:', obj.Timestamp);
collection.push(obj.Timestamp)
}
});
console.log(collection);
Where collection could be a LocalStorage, Global Variable, or something alike.
Additional info
With regard to my comment where I queried how to identify the start and end times, I ended up setting start as the smallest value and end as the largest. Here is my final code:
const collection = []
lineReader.on('line', function (line) {
var obj = JSON.parse(line);
if((obj.Event == "SparkListenerApplicationStart" || obj.Event == "SparkListenerApplicationEnd")) {
collection.push(obj.Timestamp);
if(collection.length == 2){
startTime = Math.min.apply(null, collection);
finishTime = Math.max.apply(null, collection);
duration = finishTime - startTime;
console.log(duration);
}
}
});

Auto manage and protect Created\Updated fields with Entity Framework 5

I want so every added\changed record will have a time stamp of creation\change.
But - so it will be easy to embed and easy to manage - automatically.
Overwrite the 'DbContext' class or embed this in the '.tt' file (Codefirst \ DBFirst)
The code assume so you have the fields 'CreatedOn'\'ModifiedOn' inside the POCO.
If you don't have them, or you have only one - the code will work fine.
Be aware! If you use a extension (as this one) so allow you to do batch updates or changes from a stored procedure - this will not work
EDIT:
I found the source of my inspiration - thanks 'Nick' here
public override int SaveChanges()
{
var context = ((IObjectContextAdapter)this).ObjectContext;
var currentTime = DateTime.Now;
var objectStateEntries = from v in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified)
where v.IsRelationship == false && v.Entity != null
select v;
foreach (var entry in objectStateEntries)
{
var createdOnProp = entry.Entity.GetType().GetProperty("CreatedOn");
if (createdOnProp != null)
{
if (entry.State == EntityState.Added)
{
if (createdOnProp != null)
{
createdOnProp.SetValue(entry.Entity, currentTime);
}
}
else
{
Entry(entry.Entity).Property("CreatedOn").IsModified = false;
}
}
var modifiedOnProp = entry.Entity.GetType().GetProperty("ModifiedOn");
if (modifiedOnProp != null)
{
modifiedOnProp.SetValue(entry.Entity, currentTime);
}
}
return base.SaveChanges();
}

Node.JS String encoding issues

I'm writing a sort of interface between a TCP Chat server and an SQL Server, and while working on a part where a user submits a value and is assigned a named pulled from a row in this DB with this value. When querying this DB with a value from a telnet shell, I can't get any results from the DB. But I can when I perform the same query in adminer/MySQL # BASH etc...
My thoughts are that it has come down to an encoding issue. Being rather noobish to node, I don't really know what to do. I do have a pretty good experience with JavaScript, just not node.
Code
function setCliNameOrKick(client, key){
key = String(key).replace(/\n\r\b\\\s/gi, "");
var q = "SELECT username FROM webusers WHERE lic = \'"+String(key).toString()+"\'; --";
console.log(key);
query(q);
cli.query(q, function cb(e, r, f){
if(client != null){
console.log(r);
if(r.length >= 1){
client.name = r['username'];
}else{
client.stream.end();
}
}else{
console.log("Was Passed A Null Client!");
}
});
}
That comes from the DB query tool
It takes input from a string sent by the client on connect, alongside an object representing the client
stream.addListener("data", function(data){
if(client.name == null){
data = String(data).replace(new RegExp("[\n]+", "g"), "");
cNameBuff = cNameBuff + data;
if(cNameBuff.length > 1){ //Min Length
//client.name = cNameB;
db.set(client, cNameBuff);
onAuth(client);
}
return;
}
data = String(data);
if(data.length >= 2){
srv.procChat(client, data);
}
});