4

Hello i am trying to call a method from a js file from Blazor. My file structure is like this:

-root
  -JSInterop.cs
  -js(folder)
    -meth.js  (file containing the js method)

I keep getting the following error :

 Could not find 'methods' in 'window'.

**Cs class that calls the js **

public class JSInterop {
        public static async Task<string> ChangeText() {
            try {
                var data = await JSRuntime.Current.InvokeAsync<string>("./js/meth/methods.print","mymessage");
                Console.WriteLine($"ReturnedFromJS:{data}");
                return data;
            } catch (Exception ex) {

                return ex.Message;
            }

        }
    }

Js file

function print(message){
 return "fromJs"+message;
}

window.methods = {
    print: function (message) {
        return "from js" + message;
    }
}

I have tried both putting just the method and putting it as a property in the window.I am not sure in the first case how do you refer a method from a file in js.

 "[path to file]/[containingfile]/[methodname]" ?
  or i have also tried "[path to file] / window.[methodname]"

to no avail (in the second case)

Index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width">
    <title>Sms.Studio.Web</title>
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/site.css" rel="stylesheet" />
</head>
<body>
    <app>Loading...</app>

    <!-- browser -->
    <script src="_framework/blazor.webassembly.js"></script>
    <script src="../interop/js/meth.js"></script>

</body>
</html>
Vibeeshan Mahadeva
  • 7,147
  • 8
  • 52
  • 102
Bercovici Adrian
  • 8,794
  • 17
  • 73
  • 152

3 Answers3

9

JSRuntime.Current.InvokeAsync takes a js function identifier relative to the global window scope as its first argument. So in your js file you may have :

window.methods = {
    print: function (message) {
    return "from js" + message
}

Add your js file in index.html

<script src="css/bootstrap/bootstrap-native.min.js"></script>
<script src="_framework/blazor.webassembly.js"></script>
<script src="js/meth.js"></script>

and call it from .Net as follows

await JSRuntime.Current.InvokeAsync<string>("methods.print","mymessage");
uygar donduran
  • 1,177
  • 1
  • 9
  • 20
2
// Try this:
// Don't call your class JSInterop
public class MyJSInterop {
        public static async Task<string> ChangeText() {
            try {
                var data = await JSRuntime.Current.InvokeAsync<string>("methods.print","mymessage");
                Console.WriteLine($"ReturnedFromJS:{data}");
                return data;
            } catch (Exception ex) {

                return ex.Message;
            }

        }
    }

// Js file
window.methods = {
    print: function (message) {
        return "from js" + message;
    }
};
enet
  • 41,195
  • 5
  • 76
  • 113
  • I have initially tried using the `JSRuntime.Current.InvokeAsync` right in my `cshtml` file and this error with `window` appeared.When i am delegating the `JS` calls to another class like you did here `MyJSInterop` i get a console error `Uncaught SyntaxError: Unexpected token <` in the js file. – Bercovici Adrian Jan 15 '19 at 14:55
  • 1
    A semi-colon was missing in the JavaScript return statement, which may lead to the syntax error... – enet Jan 15 '19 at 15:14
  • You also need a semi-colon like this: window.methods = {}***;*** – enet Jan 15 '19 at 15:28
  • I do not understand .I have placed a semi-colon both after the `return` and also tried after the `window.....=... ;` declaration.Still getting this error. – Bercovici Adrian Jan 16 '19 at 07:38
2

Below is an end to end example of writing cookie.

step 1 - Add MatButton and sets it onClick attribute to delegate.

<MatButton TrailingIcon="favorite" @onclick="@(async () => await AddItemtoShoppingCart(@item))" Label="add"></MatButton>

Step 2

@code{
public async Task AddItemtoShoppingCart(FoodItem selectedItem)
    {
        var test = await JSRuntime.InvokeAsync<object>("blazorExtensions.WriteCookie", "cookieName", "cookieValue", "cookieExpiryDate");
       
    }

}

Step 3 - Add below javasceipt in_Host.cshtml

<script>
        window.blazorExtensions = {

            WriteCookie: function (name, value, days) {

                var expires;
                if (days) {
                    var date = new Date();
                    date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
                    expires = "; expires=" + date.toGMTString();
                }
                else {
                    expires = "";
                }
                document.cookie = name + "=" + value + expires + "; path=/";
            }
        }
    </script>
TheKingPinMirza
  • 7,924
  • 6
  • 51
  • 81