What is alternative for angular.forEach in angular 7 - angular7

https://i.stack.imgur.com/aBY2H.png
getChartData = function(d,i,isBarChart=false){
var cData = [];
angular.forEach(d, function(value, key) {
cData.push({"key": value.key,"value": value.values[i].y});
});
//console.log(cData);
return (isBarChart ? this.toBarChart(cData) : cData);
};

You can use the methods available in javascript. A list of the methods that may be useful for your scenario:
Array.forEach(),
Array.map(), Object.keys(object)

You can use simple javascript forEach method:
Example:
let myArray = [1,2,3,4,5];
myArray.forEach((item) => {
console.log(item);
});
Your updated code:
getChartData = function(d,i,isBarChart=false){
var cData = [];
d.forEach(function(value, key) {
cData.push({"key": value.key,"value": value.values[i].y});
});
//console.log(cData);
return (isBarChart ? this.toBarChart(cData) : cData);
};

Related

indexeddb on IOS devices

I have a problem with an indexeddb query with index when running on IOS devices.
$.indexedDB(dbName).objectStore(tablename).index("INDICE").each(function(itemLocal) {
itemLocal.delete();
}, [VALORINDICE]).then(function() {
callback();
}, function() {
console.log("error");
});
The problem is if there is more than one record that matches the index, it does not eliminate them, it eliminates the first one and leaves. But if for example I put console.log (itemLocal) instead of itemLocal.delete() if it shows all those that match the index. Any suggestions of something that may be leaking?
I have tried with this code and I get the same error(code without api jquery)
var request = indexedDB.open(DATABASE_NAME);
request.onsuccess = function(event) {
var db = request.result;
var transaction = db.transaction(["TABLE"], "readwrite");
var table = transaction.objectStore("TABLE");
var index = table.index("INDEX");
var req = index.openCursor();
req.onsuccess = function() {
var cursor = req.result;
if (cursor) {
console.info(cursor.value);
cursor["delete"]();
cursor["continue"]();
}
};
req.onerror = function(e) {
console.error(e, req);
};
};
request.onerror = function(e) {
console.error(e, request);
};

addEventListener error in IE8

I'm getting an error message in ie8: Object doesn't support property or method 'addEventListener'. How can I fix this? I've seen adding an else statementand changing addEventListener to attachEvent. However, I am a bit green in the land of js and not sure where that should go, I did try a few ways.
$(document).ready(function() {
// Off canvas menu
var $slider = document.querySelector('#slider');
var $toggle = document.querySelector('.toggle-nav');
var $toggle2 = document.querySelector('nav .toggle-nav');
// var $link = document.querySelector('.link > a');
$toggle.addEventListener('click', function() {
var isOpen = $slider.classList.contains('slide-in');
$slider.setAttribute('class', isOpen ? 'slide-out' : 'slide-in');
$('#slider').animate({'right': '100%'}, 400);
});
$toggle2.addEventListener('click', function() {
var isOpen = $slider.classList.contains('slide-in');
$slider.setAttribute('class', isOpen ? 'slide-out' : 'slide-in');
$('#slider').animate({'right': '0'}, 300);
});
var toggleDataAttr = function(parentElem, toggleElem, opt1, opt2, dataAttr) {
var toggleElem = parentElem.querySelector(toggleElem);
toggleElem.setAttribute(dataAttr, toggleElem.getAttribute(dataAttr) === opt1 ? opt2 : opt1);
};
var toggle_li = document.querySelectorAll('li');
for (var i = 0; i < toggle_li.length; i++) {
toggle_li[i].onclick = function() {
toggleDataAttr(this, '.toggleContent', 'closed', 'open', 'data-state');
toggleDataAttr(this, '.toggleIcon', 'down', 'up', 'data-icon');
};
}
});
addEventListener() is not supported in IE8 and lower (more info here: http://www.w3schools.com/jsref/met_document_addeventlistener.asp), instead you need to use attachEvent() in these browsers.
You can use it like this:
if(element.addEventListener()) {
element.addEventListener('click', myFunction(), true);
} else if(element.attachEvent()) {
element.attachEvent('click', myFunction());
}
This way to do it makes it multi-browser compatible.

How to create multiple instances of IIFE Javascript module?

I'm dealing with a huge javascript codebase that I'm trying to reorganize. I'm not really an expert and I just started studying good javascript coding practices. So, one thing I'm trying to do is to divide all the code in modules. In this particular case I'm trying to create a module that would help me to optimize video embeds. I would like to pass the module an id and receive some html code or an image out of it.
I'm not putting the whole code here, but it's enough for the example:
var videoIframe = (function($) {
'use strict';
var id,
setVideoId = function(videoId) {
id = videoId;
console.log(id);
},
getVideoThumbnail = function(videoId) {
setVideoId(videoId);
},
test = function() {
console.log(id)
},
getVideoEmbedCode = function() {
};
return {
test: test,
getVideoThumbnail: getVideoThumbnail
};
})(jQuery);
In another module I assign it to two variables:
var video1 = videoIframe;
var video2 = videoIframe;
video1.getVideoThumbnail(123);
video2.getVideoThumbnail(456);
video1.test();
video2.test();
And, of course, I'm not getting what I expected. After the second getVideoThumbnail call, it always prints 456.
Doing some research I understood that I'm creating a singleton, a single instance, and I'm only changing values inside that instance. I think I need a constructor for my module, but I'm not sure how to create it in combination with the IIFE pattern. And is it the right approach?
And is it the right approach?
No. IIFEs are for things you want to do exactly once.
If you want to do something multiple times, then use a regular function and call it multiple times.
var videoIframe = (function($) {
function videoIframe() {
'use strict';
var id,
setVideoId = function(videoId) {
id = videoId;
console.log(id);
},
getVideoThumbnail = function(videoId) {
setVideoId(videoId);
},
test = function() {
console.log(id)
},
getVideoEmbedCode = function() {
};
return {
test: test,
getVideoThumbnail: getVideoThumbnail
};
}
return videoIframe;
})(jQuery);
var video1 = videoIframe();
var video2 = videoIframe();
video1.getVideoThumbnail(123);
video2.getVideoThumbnail(456);
video1.test();
video2.test();
The problem is that you are initializing object when assigning to videoIframe variable:
var videoIframe = (function($) {
// ...
})(jQuery);
You can try with:
var videoIframe = (function($) {
// ...
});
var video1 = videoIframe(jQuery);
var video2 = videoIframe(jQuery);
Just keep videoIframe as a function that returns your IIFE, instead of reusing the singleton. I kept the IIFE so the id and the inner functions keep being encapsulated and hence, not reachable if they're not in the returned interface object. If you are planning to create alot of these, it might be more efficient to just use a constructor and a prototype, so the inner functions don't get recreated for every instance.
var videoIframe = function() {
'use strict';
return (function() {
var id,
setVideoId = function(videoId) {
id = videoId;
console.log(id);
},
getVideoThumbnail = function(videoId) {
setVideoId(videoId);
},
test = function() {
console.log(id)
},
getVideoEmbedCode = function() {
};
return {
test: test,
getVideoThumbnail: getVideoThumbnail
};
}());
};
I did some minor modification. Hope it will be helpful
var videoIframe = (function($) {
'use strict';
var id;
function _setVideoId(videoId) {
id = videoId;
alert(id);
};
function _getVideoThumbnail(videoId) {
_setVideoId(videoId);
};
function _test(){
console.log(id)
}
function _getVideoEmbedCode() {
};
return {
test: _test,
getVideoThumbnail: _getVideoThumbnail
};
})(jQuery);
Now you can call like this
videoIframe.getVideoThumbnail(123);
videoIframe.getVideoThumbnail(561);
jsfiddle

How do I create an anonymous JavaScript function/callback with Dart's JS interop?

I am using Dart and its JS interop. I need to convert the following JavaScript code to Dart:
ID3.loadTags("filename.mp3", function() {
var tags = ID3.getAllTags("filename.mp3");
if (tags.artist)
artist.textContent = tags.artist;
if (tags.title)
track.textContent = tags.title;
}, {
dataReader: FileAPIReader(file)
});
Note the anonymous callback as the second parameter to loadTags. How do I create that with Dart and the dart:js library?
The closest I got was creating a named function with:
js.context['loadTagsCallback'] = () {
var tags = ID3.callMethod('getAllTags', ["filename.mp3"]);
var artistTag = tags['artist'];
var titleTag = tags['title'];
if (artistTag != null) {
artist.text = artistTag;
}
if (titleTag != null) {
track.text = titleTag;
}
};
And then using this Dart code:
ID3.callMethod('loadTags', [
"filename.mp3",
js.context['loadTagsCallback'],
new js.JsObject.jsify({'dataReader': id3FileReader})
]);
However, I don't want to create the named function. Any ideas or tips?
Dart closures are automatically converted to JS closures when sent across the border. You can just do this:
ID3.callMethod('loadTags', ["filename.mp3", () {
var tags = ID3.callMethod('getAllTags', ["filename.mp3"]);
var artistTag = tags['artist'];
var titleTag = tags['title'];
if (artistTag != null) {
artist.text = artistTag;
}
if (titleTag != null) {
track.text = titleTag;
}
},
new js.JsObject.jsify({'dataReader': id3FileReader})
]);

knockout validation - advanced search user interface

I am building an advanced search UI similar to the TFS query builder web interface. Using knockout for the client side implementation and have everything more or less working except the final validation to make certain required items are basically selected. It sort-of works as far as giving me a validation error if I select an item and then de-select the item. Which is fine, but I would like to have the form validate when hitting the search button.
I am pretty sure I need to make use of the ko.validatedobservable method, I'm just not sure exactly how. Anyway, I have a fiddle to look at: http://jsfiddle.net/sstolp/uXBSA/ if anyone has the time or inclination to help me out. I would deeply appreciate it.
Thank you for your time.
scvm.SearchLine = function () {
var self = this;
self.selectedField = ko.observable().extend({ required: true });
self.selectedOperator = ko.observable().extend({ required: true });
self.firstdate = ko.observable(new Date());
self.lastdate = ko.observable(new Date());
self.thedate = ko.observable(new Date());
return self;};
scvm.Criteria = function () {
var self = this,
lines = ko.observableArray([]),
// Put one line in by default
loadInitialData = function () {
lines.push(new scvm.SearchLine());
},
rowcount = ko.computed(function () {
return lines().length;
}),
// Operations
addLine = function () {
lines.push(new scvm.SearchLine());
},
removeLine = function (line) {
lines.remove(line);
},
search = function () {
var data = $.map(lines(), function (line) {
return line.selectedField() ? {
selectedField: line.selectedField().searchfield,
selectedOperator: line.selectedOperator().name,
} : undefined
});
alert("Send to server: " + JSON.stringify(data));
},
clear = function () {
lines.removeAll();
};
return {
lines: lines,
loadInitialData: loadInitialData,
rowcount: rowcount,
addLine: addLine,
removeLine: removeLine,
search: search,
clear: clear
};
}();
Yes, all your SearchLine objects must be wrapped into ko.validatedObservable. Also you should implement computed property which will check isValid() for each criteria line and return global validity flag.
scvm.SearchLine = function () {
var self = this;
self.selectedField = ko.observable().extend({ required: true });
self.selectedOperator = ko.observable().extend({ required: true });
self.firstdate = ko.observable(new Date());
self.lastdate = ko.observable(new Date());
self.thedate = ko.observable(new Date());
return ko.validatedObservable(self);
};
scvm.Criteria = function () {
// ...
return {
lines: lines,
loadInitialData: loadInitialData,
rowcount: rowcount,
addLine: addLine,
removeLine: removeLine,
search: search,
clear: clear,
// new property that indicates validity of all lines
linesValid: ko.computed(function(){
var items = lines();
for (var i = 0, l = items.length; i < l; i++)
if (!items[i].isValid()) return false;
return true;
})
};
}();
This new property can be used in enable binding of you "Search" button:
<input type="button"
data-bind="enable: linesValid, click: search"
title="Clicking this button will run a search."
value="Search" />
I've modified your fiddle. Take a look: http://jsfiddle.net/ostgals/uXBSA/8/
Update:
Also we should slightly modify Criteria.search method, since our line array contains observables rather than objects:
//...
search = function () {
var data = $.map(lines(), function (line) {
line = ko.utils.unwrapObservable(line);
return line.selectedField() ? {
selectedField: line.selectedField().searchfield,
selectedOperator: line.selectedOperator().name,
} : undefined
});
alert("Send to server: " + JSON.stringify(data));
},
//...

Resources