2

First of all, I've asked a simpler version of this question before delving too much about it in here. However, as I searched things up, things got more complicated and I can describe it a little more.

I'm trying to create an Electron App with Google's Blockly. Renaming variables in Blockly's domain opens up a prompt in the user's browser to ask for the new variable's name, as you can see on it's own website (click on 'Count' and choose 'Rename variable...').

The problem is: Electron doesn't support window.prompt() and it doesn't do anything if I let the code as is, so, after searching a bit, I learned that you can override Blockly.prompt to use your own. My guess: so you can use an alternative to window.prompt()

I installed electron-prompt and was trying to use it to get the user's input in the new prompt window to send it back to Blockly's core functions that handle the renaming. Here's what I'm trying:

var prompt = require('electron-prompt');
var setPrompt = function()
{ 
    return prompt
    ({
        title: 'Renaming',
        label: 'Renaming variable to:',
        type: 'input'
    })
};

var getPrompt = function()
{
    return setPrompt().then(function(value){return value})
}

var promptReturn = function()
{
    return getPrompt().then(function(value){return value})
}

Blockly.prompt = function(message, defaultValue, callback)
{
    callback(promptReturn().then(function(value){return value}));
};

EDIT: Source code from electron-prompt is here and, by looking at it and information I tried to adapt from here, I changed to the code above, inferring that prompt returns a promise. However, it seems the callback in Blockly.prompt doesn't wait for the input via the modal opened in setPrompt() and throws an error, but if I use a simple function just returning a string in callback, it works as intended...

Now I'm confused if it's about myself still using Promises wrong or if that callback in Blockly.prompt doesn't support "waiting for promises"...

Hope this helps explain what I've tried using after looking up more information about this problem.

BloodySinner
  • 95
  • 1
  • 9
  • `then()` won't return a blank string, it will return a Promise. You never look at the return value of `then()` though. You do appear to look at the return value of `promptReturn()`, which will be `undefined` because there is no `return` statement associated with your `promptReturn()` function. – Quentin Mar 22 '18 at 10:36
  • I've tried `return r` or even making `then((r) => {newName = r})`, returning `newName` with newName declared beforehand in `promptReturn()`. It says "r is not defined" and `newName` gets undefined also. I have no idea of what a Promise is, though... – BloodySinner Mar 22 '18 at 10:41
  • Good thing Google exists. It makes it easy to find out what a Promise is. – Quentin Mar 22 '18 at 10:44
  • Based on the information you provided, I found [here](https://stackoverflow.com/questions/34094806/return-from-a-promise-then) some tips. Now I'm trying `then((input) => {var newName = input})` on `promptReturn()`and `callback(promptReturn(message, defaultValue).then((newName) => {return newName}));` in `Blockly.prompt` but I'm getting "Cannot read property 'then' of undefined"... I really didn't understand how is the Promise declared in `electron-prompt`... – BloodySinner Mar 22 '18 at 12:19
  • `promptReturn` still doesn't appear to have a `return` statement, so it will return `undefined` – Quentin Mar 22 '18 at 12:21
  • Tried adding `var newName` assigning to `input` and returning it at the end of `promptReturn()`. Now I'm getting "promptReturn(...).then is not a function". – BloodySinner Mar 22 '18 at 12:32

1 Answers1

5

I managed to solve it, I'm posting it in case anyone needs a clear answer regarding Blockly.prompt overriding. It seems the callback function when overriding must return the string of the new variable, so I tried using the promise within the overriding and calling a simple function just to apply the value of then() as follows:

var prompt = require('electron-prompt');
var renameVar = function(name)
{
    return name;
}

Blockly.prompt = function(msg, defaultValue, callback)
{
    prompt
    ({
        title: 'Renaming',
        label: 'Renaming variable to:',
        type: 'input'
    }).then((name)=>{callback(renameVar(name))})
}
BloodySinner
  • 95
  • 1
  • 9
  • The `renameVar` function you provide in the callback is not doing anything but returning the name. You could just put the `name` variable directly in the callback. Also, the prompt will be overwritten for every call to `window.prompt()`, so not just for renaming variables but also creating variables. Consider using the `msg` variable to determine what the prompt is being used for, and adjust the title and label accordingly. – Paul Siersma Jun 10 '20 at 19:46