So I added this function below to my ts class:
private get(iD: string): Promise <Function> => async () => {
const tallConfig = await longCrudService.getHalf(iD);
const stream: Stream = tallConfig.stream;
const response = this.createUrl(tallConfig, stream);
return response;
}
But as soon as I add it, every other functions/Methods below it starts throwing this error: "Cannot find name 'function name'". Did I add it the wrong way?. I'm still trying to get a hold of typescript.
private get = async (id: string): Promise<Function> => {
or
private get: (iD: string) => Promise<Function> = async (iD: string) => {
What you are actually declaring here is a method. Declaring methods with arrow syntax goes like this:
private methodName = (param: ParamType): TypeOfReturnable => {
// remember to return something of type TypeOfReturnable
}
Related
So Typescript underlines this.ratesMap.get(rate[0]) and tells it's probably undefined. Adding ! solves the problem, I don't get the error anymore but the code just won't work, the output is empty and there's no other errors in the terminal and in the console.
Why typescript underlines this.ratesMap.get(rate[0]) and not this.ratesMap.has(rate[0])? How can I fix this?
export class CardStore implements ICardStore {
public lastRates: ICard[] = [];
#observable
public cardsArray: CurrencyCard[] = []
#observable
private ratesMap: Map<string, CurrencyCard> = new Map<string, CurrencyCard>();
public constructor(#inject(CardApi) private api: CardApi) {
makeObservable(this);
this.getRates();
this.updateRate();
}
#computed
public get recentRates(): CurrencyCard[] {
return this.cardsArray = [...this.ratesMap.values()]
}
private async getRates() {
const rates = await this.api.loadRates();
runInAction(() => {
Object.entries(rates).forEach((rate) => {
if (this.ratesMap.has(rate[0])) {
this.ratesMap.get(rate[0]).update(rate[1]);
} else {
let newCard = new CurrencyCard(rate[0], rate[1]);
this.ratesMap.set(rate[0], newCard);
}
});
});
}
loadrates() from the code above is here:
public async loadRates(): Promise<Record<string, number>> {
return await fetch(
`https://freecurrencyapi.net/api/v2/latest?apikey=MYAPIKEY&base_currency=USD`
)
.then(response => response.json())
.then(data => (data.data));
}
}
The return value of the get method of Map can be undefined (if the map doesn't have an entry for that key). TypeScript doesn't know that you've guarded against that with a has call.
Instead, don't use has (doing has+get is generally an antipattern anyway [a mostly harmless one 🙂], it forces traversal of the map twice). Get the card and check if you got one:
private async getRates() {
const rates = await this.api.loadRates();
runInAction(() => {
Object.entries(rates).forEach((rate) => {
const card = this.ratesMap.get(rate[0]); // ***
if (card) { // ***
card.update(rate[1]); // ***
} else {
let newCard = new CurrencyCard(rate[0], rate[1]);
this.ratesMap.set(rate[0], newCard);
}
});
});
}
TypeScript will be able to narrow the type of card based on if (card), so it will know card is not undefined in the body of the if and will let you use update on it.
I got type this problem with the following code:
"Argument of type '(response: IResponse) => void' is not assignable to parameter of type '(value: void) => void | PromiseLike'".
And problem this the check() function.
Could you please help me?
I've got really no ideas how to fix.
Thanks!
interface IResponse {
isChecked: boolean;
}
type TResponse = IResponse;
.....
function dispatchAsync<TResponsePayload>(dispatch: Dispatch, actionType: string, asyncCall: () => Promise<TResponsePayload>): any;
....
check = async () => {
const {actions, param} = this.props;
await actions.getInfoById(param.id).then(
(response: IResponse) => {
this.setState({isChecked: response.isChecked});
}
);
};
.....
getInfoById = async (id: string): Promise<void> =>
dispatchAsync<TPermission>(this.dispatch, CHECK_ACTION, async () => {
return await this.service.getInfoById(id);
});
To explain a little bit more, the TypeScript error tells you in another words that you cannot put a function that expects an argument in place of a function that doesn't expect any argument whatsoever.
Imagine code like this:
const myArg = (param: number) => setState(param + 5);
const caller = (arg: () => void) => arg();
caller(myArg);
Here is pretty obvious the caller won't provide any arguments when calling it's argument. Therefore calling the caller with myArg will result in an error thrown inside the myArg as it won't receive the argument it expects.
In your example the getInfoById returns Promise<void>. That means the then method will not provide any argument to the provided callback. That is the root cause.
You can fix it by telling the TypeScript that getInfoById actually returns something inside the promise (in this case I assume it is the IResponse type).
Like so:
getInfoById = async (id: string): Promise<IResponse> =>
dispatchAsync<TPermission>(this.dispatch, CHECK_ACTION, async () => {
return await this.service.getInfoById(id);
});
You can look at your code below:
getInfoById = async (id: string): Promise<void> =>
dispatchAsync<TPermission>(this.dispatch, CHECK_ACTION, async () => {
return await this.service.getInfoById(id);
});
You can change void in your Promise<void> with any or your spesific data type.
Because you can use return if you use void.
I have this function, but when compiling the app.
public async test(options?: { engine?: Config }): Promise<any> {
const hostel = new Service({
list: this.servicesList,
createService: list => this.dbService.buildService(list)
});
return hostel.load();
}
I have this error:
26:27 error Missing return type on function
#typescript-eslint/explicit-function-return-type.
on this line createService: list => this.dbService.buildService(list) text**
You only should add return in the function
public async test(options?: { engine?: Config }): Promise<any> {
const hostel = new Service({
list: this.servicesList,
createService: list => this.dbService.buildService(list)
});
return hostel;// Missing line
}
As mentioned by Andrew in the comments, you are not returning anything from the function. If that's what you expect, just change Promise<any> to Promise<void>
I am using Javascript/Typescript in order to format a password value on a collection of PersonModel objects. I am executing a Promise on each element in the Collection.
I am using Promise.all to allow all Promises to complete, and then want to return the formatted collection.
However, I get an error at build time.
PersonService.ts
private decryptPersons(persons: PersonModel[]): Promise<PersonModel[]> {
return new Promise<PersonModel[]>(resolve => {
let promises: Array<Promise<string>> = [];
let decryptedPersons: PersonModel[] = [];
for (let i: number = 0; i < persons.length; i++) {
let ciphertext: string = persons[i].password;
promises.push(this.decrypt(ciphertext).then((password: string) => { // <== line 357
persons[i].password = password;
decryptedPersons.push(persons[i]);
}));
}
Promise.all(promises).then(() => {
resolve(decryptedPersons);
});
});
}
private decrypt(value: string): Promise<string> {
return new Promise<string>(resolve => {
this.encrypter.decrypt(value).then((result: string) => {
resolve(result);
});
});
}
Error
ERROR in ./app/pages/service/personService.ts
(357,31): error TS2345: Argument of type 'Promise<void>' is not assignable to parameter of type 'Promise<string>'.
Type 'void' is not assignable to type 'string'.
I am no expert with Javascript, so my structure may me incorrect. If anyone can advise, I would appreciate it.
You're trying to push the following into your promises array:
this.decrypt(ciphertext).then((password: string) => { // <== line 357
persons[i].password = password;
decryptedPersons.push(persons[i]);
})
but your function here doesn't return anything, so this is going to evaluate to a Promise<void>.
You're also abusing the "explicit promise construction antipattern" in several places here.
Give this a try:
private decryptPersons(persons: PersonModel[]): Promise<PersonModel[]> {
return Promise.all(persons.map(person =>
this.decrypt(person.password)
.then(password => {
person.password = password;
return person;
});
));
}
private decrypt(value: string): Promise<string> {
return this.encrypter.decrypt(value);
}
I'm working with an existing TypeScript method and I'm struggling to get the errorCallback value from the promise. The Interface looks like the following from the Type Definition file for Angular:
interface IPromise<T> {
then<TResult>(successCallback: (promiseValue: T) => IHttpPromise<TResult>, errorCallback?: (reason: any) => any, notifyCallback?: (state: any) => any): IPromise<TResult>;
then<TResult>(successCallback: (promiseValue: T) => IPromise<TResult>, errorCallback?: (reason: any) => any, notifyCallback?: (state: any) => any): IPromise<TResult>;
then<TResult>(successCallback: (promiseValue: T) => TResult, errorCallback?: (reason: any) => TResult, notifyCallback?: (state: any) => any): IPromise<TResult>;
The TypeScript method I'm working with calls a service and the promise uses the return (this works):
public loadSavedLogin(): ng.IPromise<MyApp.Models.User> {
return this._myAppService.getUser(this.savedUserId).then((result: MyApp.Models.User) => {
if (result) {
this.userId = result.UserID;
this.userName = result.UserName;
}
return result;
});
}
The problem is I have no idea how to get the errorCallback value. If I place a comma after .then((result: MyApp.Models.User), I see Intellisense showing me the errorCallback parameter, but I just can't get any of the syntax working. In raw JS, I'd have a comma at the end with another function accepting the error value, but I'm not sure with this interface how to get the error returned.
How do I modify the function to get the error value if the service call returns one using IPromise?
Here is a simplified example to help you out.
class Test {
public _test: ng.IPromise<string>;
// This method has a return type of ng.IPromise<string>
// You must return a value of this type.
public example(): ng.IPromise<string> {
return this._test.then(
// Success
// Must return a string to be compatible with
// the ng.IPromise<string> return type
(val) => {
alert('Success');
return val;
},
// Error
// Should also return a string to be
// compatible with the return type
(reason) => {
alert('Error: ' + reason);
return '';
});
}
}
Because the example method return type is ng.IPromise<string>, the success function and the error function in the then method must return a string in order for the types to all match up.
In your case, they should return an instance of an MyApp.Models.User.
I suspect in your error function you weren't returning a value - but this makes the best common type between the success and error function void.
Further example... using just an array to show best common types when using functions:
var example = [
(input: string) => { return 'String'; },
(input: string) => { console.log(input); }
];
The best common type used in this example is (input: string) => void. Seems strange - but it actually makes sense. If you call the functions in this array, don't expect to get a return value.
So just make sure your success and error functions have the same return type and all the types will match up for you.
public loadSavedLogin(): ng.IPromise<MyApp.Models.User> {
return this._myAppService.getUser(this.savedUserId).then(
(result: MyApp.Models.User) => {
if (result) {
this.userId = result.UserID;
this.userName = result.UserName;
}
return result;
},
(reason: string) => {
return <MyApp.Models.User> null;
}
);
}