Jason Garner
Jason Garner

Reputation: 67

Using a variable in _Host.cshtml

I have an app that loads a JavaScript library from a 3rd party vendor in my head tag on _Host.cshtml. Depending on the browser request, I need to swap out the src attribute and load a different library because the src link will change.

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PictometryHost</title>
<base href="~/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link href="css/site.css" rel="stylesheet" />

<!-- include the IPA JS Library from pictometry -->
<script type="text/javascript" src="http://pol.pictometry.com/ipa/v1/embed/host.php?apikey=someapikey"></script> <----This right here I need to change on the fly.
<script src="~/Pictometry.js"></script>

On my index.razor page, I have created a property IpaJsLibUrl that will load the proper src attribute link into.

I would like to just inject this property into the src attribute in the script tag if possible. But any way I can dynamically change this src attribute to what I want would be fabulous!

Upvotes: 1

Views: 945

Answers (1)

Umair
Umair

Reputation: 5481

There is a way of loading the scripts dynamically in the page. But the way you are suggesting will not work. Instead, use the below process I found on another StackOverflow answer:

Create a js file called scriptLoader.js

// loadScript: returns a promise that completes when the script loads
window.loadScript = function (scriptPath) {
    // check list - if already loaded we can ignore
    if (loaded[scriptPath]) {
        console.log(scriptPath + " already loaded");
        // return 'empty' promise
        return new this.Promise(function (resolve, reject) {
            resolve();
        });
    }

    return new Promise(function (resolve, reject) {
        // create JS library script element
        var script = document.createElement("script");
        script.src = scriptPath;
        script.type = "text/javascript";
        console.log(scriptPath + " created");

        // flag as loading/loaded
        loaded[scriptPath] = true;

        // if the script returns okay, return resolve
        script.onload = function () {
            console.log(scriptPath + " loaded ok");
            resolve(scriptPath);
        };

        // if it fails, return reject
        script.onerror = function () {
            console.log(scriptPath + " load failed");
            reject(scriptPath);
        }

        // scripts will load at end of body
        document["body"].appendChild(script);
    });
}
// store list of what scripts we've loaded
loaded = [];

The purpose of the above code will be to create a <script> tag on the page when we want to, for example when a new page is opened.

Next, let us inject and use the famous IJsRuntime interface to talk to the above js file:

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        // invoke script loader
        await jsRuntime.InvokeVoidAsync("loadScript", "https://code.jquery.com/jquery-3.4.1.js");
        await jsRuntime.InvokeVoidAsync("loadScript", "myJQueryTest.js");

        await jsRuntime.InvokeVoidAsync("setH1", "Hello world!");
    }

As you can see we have loaded 2 js file, one jquery library and the other is our custom myJQueryTest.js js file. And also were able to can the method setH1 in our custom library:

window.setH1 = function (message) {
    $('h1').text(message);
}

Upvotes: 1

Related Questions