Getting TypeError when recreating Lodash dropWhile() method in Javascript for an assignment - lodash

I get the error: "TypeError: arrayslice is not a function" in "const droppedArray = array.slice(n)" when my dropWhile() method calls the drop() method (below).
I'm confident that the dropWhile() method is correct - so no changes needed here.
I've tried problem solving the TypeError in the drop() method and reworking the code - but keep going in circles with this - can you tell me what is going wrong and how to fix this? I'm sure it's something simple...
drop: function(array,n){
if( n ===undefined){
var n = 1;
}
const droppedArray = array.slice(n);
return droppedArray;
},
dropWhile: function(array,predicate){
const dropNumber = array.findIndex(function(element, index){
return !predicate(element, index, array)
});
const dropArray = this.drop(dropNumber);
return dropArray;
}

I think you forgot to pass the array in your drop function:
const dropArray = drop(dropNumber); // <-- missing the array param
Should be:
const dropArray = drop(array, dropNumber);
What happens now is your drop function is trying to call slice on the index found by this row:
const dropNumber = array.findIndex(function(element, index){
Here is a fiddle to illustrate

Related

Unable to Pass Two Parameters as Argument to Javascript Function

I am trying to use karate.call to invoke function of a JS file receiving two arguments (String, Array of String). However the array of string would not be passed on to the JS file.
The JS file contains:
function(query, fragments) {
// Here lies some code
// One of them includes fragments.length;
}
And I call the JS function on another JS file in this way:
//var query = 'Some string';
//var fragments = ['fragment1', 'fragment2'];
var clean = karate.call('../helper/helper.js', [query, fragments]);
I am able to pass query which is a string. But I was unable to pass the array of string. The error says:
TypeError: Cannot read property "length" from undefined
It seems the array of string did not get passed to the JS function. Any help will be greatly appreciated. Thanks!
You can read you function first and invoke is just like any other js function
var myFun = karate.read('../helper/helper.js');
var funCall = myFun(query, fragments);
or
var myCall = karate.read('../helper/helper.js')(query, fragments);
this should work.
.call takes parameters as comma separated values , you need to use .apply if you want to pass values as an array.
var clean = karate.call('../helper/helper.js', query, fragments);
will work...
The answers here are missing an important clarification:
I often do single arg functions like:
* def concatParams =
"""
function(s) {
return "urldt=" + todaysDate + "&caseid=" + s.caseid
}
"""
And I will call that like so:
* def params = call concatParams {caseid: '3433344'}
But, when I want to do 2 params, I will define a function like so:
* def concatParams =
"""
function(d,s) {
return "urldt=" + d.date + "&caseid=" + s.caseid
}
"""
And unintuitively, neither of these will work:
* def params = call concatParams {date: '01/01/2020', caseid: '3433344'}
* def params = call concatParams '01/01/2020' '3433344'
To get it to work, instead I call it like this:
* def params = concatParams('01/01/2020', '3433344')
Documentation does not clarify this.
var clean = karate.call('../helper/helper.js', query, fragments);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
call method accepts comma separated params and apply accept array so you need to replace call into apply. your code looks like
function karate(query, fragments) {
// Here lies some code
// One of them includes fragments.length;
}
var clean = karate.apply('../helper/helper.js', [query, fragments]);

Set several initial dates in inline datetimepicker tempusdominus

I'm trying to set up the datetimepicker on
https://tempusdominus.github.io/bootstrap-3/
and configure it to be used inline. It is initialized with:
$('#datetimepicker5').datetimepicker({
inline: true,
allowMultidate: true,
multidateSeparator: ';',
locale: 'nb',
format: 'L',
useCurrent: false,
});
It works, but I cannot find out how to initialize several dates.
As you can see I use it with allowMultidate.
So, how can I initialize the datetimepicker with several dates pre-set?
I met the same problem and I can't find any answers here. So I tried to resolve it with a little revise to "tempusdominus-bootstrap-4.js".
I hope this will help you and make some reference for anyone who met the same problem.
At first adding a method multiDate for Object DateTimePicker.
var DateTimePicker = function () {
…
DateTimePicker.prototype.multiDate = function multiDate(params) {
var date = params[0];
var index = params[1];
this.date(date, index);
};
…
}
The next, invoke your method at your page.
Suppose your initial data is like this:
var values = ['2019-02-06','2019-03-06','2019-05-08','2019-07-02'];
So you can initialize these in your multidatepicker.
var initializeMultidate = function(){
for(var i=0; i<values.length; i++){
var date = moment(values[i], 'YYYY-MM-DD');
$("#datetimepicker1").datetimepicker("multiDate", [date, i]);
}
};
=================================================
That's all.
The only solution I found was to do a search for the dates and using JQuery to click them, it is not elegant but it worked for me.
var fechas = ['01/10/2020', '02/10/2020', '03/10/2020'];
for (let index = 0; index < fechas.length; index++) {
$("[data-day='"+fechas[index]+"']").click();
}
Unfortunately, what you are asking cannot be done using tempusdominus. I struggled with the same issue and in the end switched over to jQueryUI MultiDatesPicker, which allows for much more control.
http://dubrox.github.io/Multiple-Dates-Picker-for-jQuery-UI/

Vue Object isn't returning updated value despite seeing the value updated

I'm writing tests for Vue.js and I'm trying to write the test to ensure that when some props are changed for pagination, the resulting values within the component are updated properly.
So when I console.log the component, I see the correctly updated values, but then when I try to literally grab that attribute it gives me the old and outdated value. Look at rangeList in the following screenshot to see what I mean:
Here is my code so that you see how what is generating this output.
pagComp.$refs.component.limit = 10;
pagComp.$refs.component.pages = 145;
console.log(pagComp.$refs.component);
console.log('RangList: ' + pagComp.$refs.component.rangeList.length);
Here is the code that modifies rangeList:
createListOfRanges() {
let range = [];
for(let i = 0; i < this.pages; i++) {
range.push(i);
}
this.rangeList = [];
while(range.length > 0) {
this.rangeList.push(range.splice(0, this.rangeLength));
}
this.correctLastRange();
},
Finally, there are two places this function is called: when the component is being created, and when the pages attribute changes. Here is the watcher:
watch: {
pages(val) {
this.createListOfRanges();
}
},
I see some issues with this part of your code:
while(range.length > 0) {
this.rangeList.push(range.splice(0, this.rangeLength));
}
range.splice(..) returns an array, which is getting pushed into this.rangeList
Forget about that for a minute. Look at the following example:
x = [1, 2, 3, 4]
x.splice(0, 2) // result: [1, 2]
As you can see above, splice returns an array, not an element. Now, in the same example above:
x = [1, 2, 3, 4]
y = [10, 11]
y.push(x.splice(0, 2))
Check the value of y. It will be [10, 11, [1, 2] ]. It is an array within another array. It does not look very meaningful here. You can do the above x and y experiments directly in your developer console.
In your case, your x happens to be the local range array within createListOfRanges method, and your y is this.rangeList that belongs to your Vue component.
Can you check your app logic at around that area, and see if that is really what you want to do?
For debugging Vue.js apps, you also need Vue devtools: https://github.com/vuejs/vue-devtools - it is much better than console.log()
While #Mani is right on the line of code giving you issues is your push to rangeList.
createListOfRanges() {
let range = [];
for(let i = 0; i < this.pages; i++) {
range.push(i);
}
this.rangeList = [];
while(range.length > 0) {
this.rangeList.push(range.splice(0, this.rangeLength));
}
this.correctLastRange();
},
pushing the result of the splice just makes a single element with all the elements of range in it.
try changing it to
this.rangeList.push(range.shift());
Though your function could be simplified by pushing the for(let i = 0; i < this.pages; i++) { i value directly to rangeList unless that's a simplification.
This JSFiddle shows what I'm talking about.
I appreciate the answers above, however they aren't what the issue was.
The problem was with Vue's lifecycle. I'm not 100% sure why, but when the page and limit variables are changed it takes another moment for the page watcher (shown above) to get executed and update the component. So thus it wouldn't show up in my tests. So what I did was use nextTick like so, which fixed the problem.
pagVue.limit = 10; // limit and pages change together every time automatically
pagVue.pages = 145;
Vue.nextTick(() => {
expect(pagination.rangeList.length).toBe(25);
})

Implement the same function in AS2 for an Array

I have an array, and I would like to make a function onRelease for all of the array positions.
The code would be like:
pick = new Array(2,3,4);
var botoes1:MovieClip = lev.attachMovie("block", "block_"+lev.getNextHighestDepth(), lev.getNextHighestDepth(), {_x:550, _y:1*22});
_root.botoes1.gotoAndStop(pick[1]);
var botoes2:MovieClip = lev.attachMovie("block", "block_"+lev.getNextHighestDepth(), lev.getNextHighestDepth(), {_x:550, _y:2*22});
_root.botoes2.gotoAndStop(pick[2]);
var botoes3:MovieClip = lev.attachMovie("block", "block_"+lev.getNextHighestDepth(), lev.getNextHighestDepth(), {_x:550, _y:3*22});
_root.botoes3.gotoAndStop(pick[3]);
for(i=0;i<3;i++){
_root['botoes'+i].onRelease() = Function () {
}
}
but it doesn't work this way...
and if possible, how can I make the MovieClip declaring for all the buttons in an for loop?
Couple syntax errors there, here's what this line should look like:
_root['botoes' + i].onRelease = function()
{
// Function body.
//
}
Your previous code was trying to assign the result of _root['botoes' + i].onRelease() (which would have been undefined) to the result of Function() (which would have been a Function object).

Determing if a SQL select returns an empty set asynchronously?

Is this possible easily? It seems the handleResult method is only executed if the result isn't the empty set.
A thought I had was to have handleResult and handleCompletion be member functions of an object and have handleResult update a member variable that handleCompletion can check. If the variable is set, not empty, if variable unset, empty and can act accordingly.
seems to be overly complicated and hoping there's a better solution?
to sketch out a solution (the thought i had above) (edit2: per comment I made below)
function sql() {
this.results = false;
var me = this;
this.handleResult = function(aResultSet) {
for (var row = aResultSet.getNextRow(); row; row = aResultSet.getNextRow()) {
me.results = true;
var value = row.getResultByName("name");
}
};
this.handleError = function(aError) {
.... //deal with error
};
this.handleCompletion = function(aReason) {
if (me.results) {
....//results
} else {
....//no results
}
if (aReason != Components.interfaces.mozIStorageStatementCallback.REASON_FINISHED) {
....//handle these
};
};
s = new sql();
statement.executeAsync({
handleResult: s.handleResult,
handleError: s.handleError,
handleCompletion: s.handleCompletion
});
is this considered a good way to solve this problem?
edit1: this doesn't behave in the manner I'd expect (it works, but not 100% sure why). i.e. the this.results variable is undefined (not false), if handleResult never runs. So it appers as if handleResult and handleCompletion are operating on a different set of variables than I'd expect.
any help to understand what I'm doing wrong would be appreciated.