Variable becoming undefined in Promise function - arrays

I have an array (targets) in global scope, the values of which I am passing to an external function [third party library, externalConverter] that does some text conversion. The values of this array are being passed in to the convert function and the conversion is happening fine.
const targets = [‘box’, ’box1’, ’box2’, ’box3’]
for (var i = 0; i < targets.length; ++i) {
console.log(targets[i]); // this is coming out fine
externalConverter
.convert(data.text, targets[I])
.then(results => {
data.convertedText.push({
[targets[i]]: results[0]
});
//above convertedText array comes out as
//{“undefined: ”, “nice converted text”}, ...
})
}
Inside the result of the Promise, I am trying to access the targets values but getting undefined values inside the function above. I am not sure why targets is suddenly becoming undefined
Any ideas?

The value of i will have progressed to its final value (i.e. targets.length) before any of the then callbacks have executed, and so any use of i as index will be out of range.
Use let i instead of var i to make separate instances of i that will not have this problem.

Related

TypeScript difference between any[] and [] when initialize data type

I used *ngIf to judge the array length in html
<div *ngIf="apps.length === 0">
and define the apps in .ts file
public apps: any[];
and apps was retrieved from the rest api data:
ngOnInit() {
const refSpinner = this._simsSpinnerService.showSpinner('my-apps-spinner');
const getMyApps = this._myAppsService.getMyApps().pipe(share(), finalize(() => { this._simsSpinnerService.stopSpinner(refSpinner); }))
this._subscriptions.push(getMyApps.subscribe({
next: (data) => {
if (data && data instanceof Array) {
debugger
this.apps = data;
}
},
error: (err) => MessageService.addError(err)
}));
}
The console will print error message:
ERROR TypeError: Cannot read properties of undefined (reading 'length')
at MyAppsComponent_Template (my-apps.component.html:13:30)
I add debugger and found the this.apps is undefined before the data was assigned to it.
Then I changed the way to init data type like:
public apps = [];
And the error was disappeared, found that this.apps is an array before the data was assigned to it.
I searched and found that
any[] is an array where the item is of type any.
But why is it undefined? Shouldn't it be a array of any elements in it?
I believe this is because the original code used a declaration, while the update code has initialization.
Declaration
Declaration tells the compiler the variable name and type. It does not give the variable a value (or rather, it gives it undefined). In other words, it declares what the variable is.
public apps: any[]; // apps = undefined
Initialization
To actually give the variable a value other than undefined, we have to initialize it.
public apps = []; // apps = []
The compiler can then infer the type of the variable apps, which is, in this case, Array<any>
This alone isn't enough to explain why the compiler errors, however. Because you can keep a variable uninitialized as long as you give it a value later. However, you attempt to read the variable's length with <div *ngIf="apps.length === 0">, which results in an error (as undefined has no property length)

How can I enable strict type checking on React component functional props? [duplicate]

Why there aren't any compilation errors in this code?
Code:
function partial(f: (a: string) => string, a: string) : string {
return "";
}
var test = () => "";
var result = partial(test, "");
Function "partial" takes as the first argument a function, that takes one parameter, but I pass to it function, that doesn't take any parameters, and typescript compiler thinks, that this is OK. I understand that this can't break anything because you can pass all parameters in the world to the function that doesn't take any, and it won't break anything, but it should be a compilation error because typescript is about types and there is an obvious type missmatch and it can possible be a developer's error.
Is there any workarounds for this problem?
there is an obvious type missmatch and it can possible be a developer's error.
There's nothing obviously wrong with this code. Consider something like this:
let items = [1, 2, 3];
// Print each item in the array
items.forEach(item => console.log(item));
Is this code correct? Definitely! But forEach invokes its provided function with three arguments, not one. It would be tedious to have to write:
items.forEach((item, unused1, unused2) => console.log(item));
Note that you can still get errors if you try to do something that's actually wrong. For example:
function printNumber(x: number) { console.log(x); }
let strings = ['hello', 'world'];
strings.forEach(printNumber); // Error, can't convert string to number

pass array values as parameters of function swift

im new to swift.I tried to follow many tutorials but still im not able to find a solution for it.
I want to pass values stored in an array to a function.
let trackList = ["AC","BB"]
for trackId in trackList{
let ind = trackList.index(of: trackId)
let index = trackList.startIndex.distance(to: ind!)
let num = Int(String(describing: ind))
let track = String(trackId)
addDiaryList(track:String) //i keep getting error here saying: Cannot convert value of type 'String.Type' to expected argument type 'String'
}
func addDiaryList(track:String) {
}
That's easy, the function call is wrong. It should be
addDiaryList(track:track!)
The first track stands for the parameter name in the function, the second one for the variable you assigned two rows above.
But I think you're doing a lot of useless calls here, it could rather be:
let trackList = ["AC","BB"]
func addDiaryList(track:String) {
}
for trackId in trackList{
addDiaryList(track: trackId)
}

how to pass the value in protractor like this element(by.model('filter.dateRange')).$('[value="<parameter>")

I need to pass the value say in the below example as 'date' to identify the element in the page.
I am working with Angularjs page automation using protractor with Javascript.
function(parameter) {
element(by.model('filter.dateRange')).$('[value="parameter"]');
}
How to give the value in the above expression from the function call.
i.e, How to pass different values to the parameter. now parameter becomes string.
Use a array variable in place of parameter string and try to loop it through all the values of that variable. Additionally if you are working on the result of finding the element, you should be using then functionality of protractor. Here's the link to it - then-protractor
var parameter = ['Yesterday', 'today']; //fill in your values
function(parameter) {
var func = function(val){
element(by.model('filter.dateRange')).$('[value="+parameter[val]+"]');
};
for (var i = 0; i < parameter.length; ++i) {
func[i];
};
};
Hope this helps.

List.forEach unable to modify element?

I'm attempting to create a list of lists to imitate the functionality of a 2D array in Dart, and I was having trouble for a while figuring out how to make it work.
I originally used List.forEach in order to create the lists and fill them, but after each loop, it's as if I never created the lists. Here's what that code looked like:
currentMap = new List<List<int>>(height);
currentMap.forEach((e) {
e = new List<int>(width);
e.forEach((f) {
f = 1;
});
});
Printing currentMap resulted in a list of null. Here's what I have now:
currentMap = new List<List<int>>(height);
for(int i = 0; i < height; i++) {
currentMap[i] = new List<int>(width);
for(int j = 0; j < width; j++) {
currentMap[i][j] = 1;
}
}
This works exactly as I expected it to.
I understand that this is probably a very basic issue, and I am assuming that forEach does not allow you to modify the element, but I wanted some confirmation on that, and the Dart API docs do not specify except with the phrase "apples the function f to each element..." which may just not be clear to me.
Also, I am aware of things like the List.filled() constructor -- this is just how I am starting to build towards other functionality.
EDIT: Okay, I think I understand now. Arguments are "pass-by-sharing" which means that a copy of a reference to the object is made. This means that you can modify a member of a mutable object that is pointed to by the argument (as follows):
void function(MyObject o) {
o.x = 5;
}
but trying to change what o points to will not change the argument after exiting the function, such as this:
void function(MyObject o) {
MyObject p = new MyObject();
o = p;
}
Dart does not have variable references, all elements are passed as a reference to an object, not to a variable. (In other words, Dart is purely "call-by-sharing" like both Java and JavaScript).
That means that the e parameter to the forEach callback is just a normal local variable, and assigning to it has no effect outside the callback. The same goes for iterators: they return the value in the iterable, but it has no reference back to the iterable after that.
The double loop is what you want when you do "read-modify-write". You read a value from the list, modify it and store it back into the list using the list's index-set operator.
I know you know about List.filled, but just for other readers, I'll give the one-liner to create the two-dimensional array initialized to 1 values:
currentMap = new List.generate(height, (_) => new List.filled(width, 1));
This is because e is only a reference to the List in currentMap not to a currentMap item.
You update a copy of the reference to a List, but this reference has no connection to currentMap.
After the loop, e just gets garbage collected.
This is because of how an Enumerator works and I believe because the Enumerator is immutable You can't modify the collection items when it's being processed in a foreach... removing members and such.
See also:
http://msdn.microsoft.com/en-us/library/ttw7t8t6.aspx
What is the best way to modify a list in a 'foreach' loop?

Resources