Skip to main content

Adding notification from server side, code ignoring ExecuteOrDelayUntilScriptLoaded [Resolved]

I'm trying to add a UI notification from server side. To do this, I've written this code in one of my code behind event handler:

    private void AddNotifySuccessScript()
    {
        var scriptTemplate = "ExecuteOrDelayUntilScriptLoaded(function(){{ SP.UI.Notify.addNotification(\"{0}\",true); }}, 'sp.js');";
        var script = string.Format(
            scriptTemplate,
            "Message".Replace("\"", "\\\"") // TODO: message in parameters
            );
        Page.ClientScript.RegisterStartupScript(typeof(MyControl), "notifysuccess", script, true);
    }

This is resulting in this JS code produced in the page :

ExecuteOrDelayUntilScriptLoaded(function(){ SP.UI.Notify.addNotification("Message",true); }, 'sp.js');

Which is, I believe, expected.

However, when I execute the page, I got a client side error:

SCRIPT5007: The value of the property 'addNotification' is null or undefined, not a Function object

Especially, the code breaks in this SharePoint code (the addNotification method is undefined at this point) :

SP.UI.Notify.addNotification = function(strHtml, bSticky) {ULS5Vl:;
    return addNotification(strHtml, bSticky);
}

But if I let the page reach the end, I can see that the addNotification is eventually available.

How can I fix this? It looks like that for some reason, my function is fired before the actual load of the sp.js file.


Question Credit: Steve B
Question Reference
Asked July 11, 2019
Posted Under: Sharepoint
64 views
4 Answers

I finally find a way to solve my issue. Here is the modified script :

    private void AddNotifySuccessScript()
    {
        var scriptTemplate = @"
ExecuteOrDelayUntilScriptLoaded(function(){{
    ExecuteOrDelayUntilScriptLoaded(function(){{
        SP.UI.Notify.addNotification(""{0}"",true);
        }},
    'core.js'
    )}},
'sp.js'
);";
        var script = string.Format(
            scriptTemplate,
            "Message".Replace("\"", "\\\"")
            );
        Page.ClientScript.RegisterClientScriptBlock(typeof(GenericFormWebPartUserControl), "notifysuccess", script, true);
    }

With the help of Andrey Markeev, I find that the addnotification depends on two script files. Here I nest my on demand load of these script to be sure both are loaded.

I didn't succeed in using the "inplview" dependency though.


credit: Steve B
Answered July 11, 2019

addNotification function resides in core.js file, while SP.UI.Notify.addNotification is found in sp.js. As you probably know, all those SharePoint javascript files are registered on page and loaded there via Script-On-Demand (SP.SOD) system.

Obviously these files have dependencies, and my investigation shows (see the screenshot below) that sp.js is not marked as dependent from core.js for some reason:

enter image description here

Thus to solve this issue, you can use some script which is dependent from both sp.js and core.js. For example, it can be "inplview" (notice, no ".js" at the end!):

enter image description here

Thus I propose you to try the following code:

    var scriptTemplate = "ExecuteOrDelayUntilScriptLoaded(function(){{ SP.UI.Notify.addNotification(\"{0}\",true); }}, 'inplview');";

P.S. I never experienced this behavior, although I use SP.UI.Notify very often. And I always use "sp.js" for ExecuteOrDelayUntilScriptLoaded. I assume the cause of the problem you're facing is that you use "RegisterStartupScript", and somehow sp.js appears in the load queue before the "core.js" file.


credit: Andrey Markeev
Answered July 11, 2019

I've found that it SP.UI.Notify is defined in different places depending on which version of SharePoint you've got.

2010 - is sp.js so

ExecuteOrDelayUntilScriptLoaded(your_function,"sp.js");

2013 - is core.js so

ExecuteOrDelayUntilScriptLoaded(your_function,"core.js");

credit: Ryan
Answered July 11, 2019

For SharePoint Online:

ExecuteOrDelayUntilScriptLoaded(your_function,"core.js");

In some cases, sp.js works but it is no consistent.

For older versions & on-premise, I had success with below:

ExecuteOrDelayUntilScriptLoaded(your_function,"sp.js");

credit: Anand
Answered July 11, 2019
Your Answer