0

I am trying to write an Obsidian plugin. I am stuck with Promise object when trying to call an API for example and trying to fill the results object inside query function.

How can I possibly fill results object inside query function.

Note that I cannot change the signature of getItems method as it is from the Obsidian base class FuzzySuggestModal.

export default class DictionarySuggester extends FuzzySuggestModal<string> {

    async getAutocompleteItems(term: string) {        
        const response = await request({ url: this.autocompleteUrl.replace('{0}', term) });
        return response;
    }

    query(term: string): any {
        const results = [];
        const searchTerm = term.toLocaleLowerCase();
        
        // Problem here, calling await
        var response = await this.getAutocompleteItems(searchTerm);

        var jsonObj = JSON.parse(response);
        for(var i = 0; i < jsonObj.results.length; i++) {
            var term= jsonObj.results[i].term;
            results.push(term);
        }

        return results;
    }

    getItems(): string[] {
        let searchTerm = '';

        // logic to get the searchTerm

        return searchTerm === '' ? [] : this.query(searchTerm);
    }

}
Furqan Safdar
  • 16,260
  • 13
  • 59
  • 93
  • 1
    You can't synchronously return the result of an asynchronous process. – jonrsharpe May 06 '23 at 08:03
  • That is why I have asked this question how to counter this situation. – Furqan Safdar May 06 '23 at 08:05
  • 1
    You literally can't. – Styx May 06 '23 at 08:07
  • 1
    Unless query lets you return a promise (`any` is a bit vague) or something similar (like an RxJS observable) or accepts a callback, you can't. But looking in https://marcus.se.net/obsidian-plugin-docs/reference/typescript/classes/FuzzySuggestModal and up the inheritance tree I don't see `query`. – jonrsharpe May 06 '23 at 08:11
  • Though, you can return empty object which will be populated _later_, when you async call will be complete, but I doubt you meant that, right? – Styx May 06 '23 at 08:13
  • @jonrsharpe, you are right perhaps the query function is calling from within getItems(): string[] { } function which is from the Obsidian base class. But eventually the question is how to overcome this situation – Furqan Safdar May 06 '23 at 08:20
  • Editted my question and added getItems function – Furqan Safdar May 06 '23 at 08:22
  • 1
    Read the comments, the linked questions. You can't overcome it. If `getItems` has to synchronously return an array of strings, you **cannot** have an async function supplying them. – jonrsharpe May 06 '23 at 08:24
  • So are you saying it is an impossible situation to handle by any means? – Furqan Safdar May 06 '23 at 08:27
  • 2
    @FurqanSafdar — Four different people have told you that in four different ways. – Quentin May 06 '23 at 09:31
  • 1
    Note there is a superclass of FuzzyModal, https://marcus.se.net/obsidian-plugin-docs/reference/typescript/classes/SuggestModal which anticipates `getSuggestion` being asynchronous as you can see from the signature `abstract getSuggestions(query: string): T[] | Promise;`. However, it looks like FuzzyModal abandons this general signature, and constrains it to a synchronous implementation `getSuggestions(query: string): FuzzyMatch[];`. Perhaps you could subclass from SuggestModal directly, and fulfil the signature of its `getSuggestions()` which DOES expect an async implementation. – cefn May 06 '23 at 09:36
  • @cefn, appreciate your input, that's appears to be a very good suggestion indeed and I hope it would be helpful to overcome this situation. – Furqan Safdar May 06 '23 at 13:56

0 Answers0