Asked by:
Early-bound JavaScript throws 'Sdk' is undefined error

Question
-
I am attempting to use the early-bound JavaScript classes as per the Sdk.Soap.js project in CRM 2013 SDK. I have added the Sdk.Soap.min.js file to my CRM Form as a Web Resource. I have also added my Entity-specific class JavaScript files (generated through the Entity Class Generator project) as Web Resources to the Form. I am running into a problem when the form loads for the first time. When the Entity-specific JavaScript files load, they are throwing the error: "'Sdk' is undefined". This is most likely as a result of the following line that gets added to the Entity-specific JavaScript files:
Sdk.md = window.Sdk.md || { __namespace: true };
Apparently the Sdk.Soap.min.js Web Resource (where the Sdk namespace has been defined) has not yet loaded when the Entity-specific script is loaded and run. After the Sdk.Soap.min.js file has been cached by the browser there is no longer a problem on subsequent form loads. I have tried rearranging the load order of the scripts in the CRM Form, to no avail. I cannot find a way to make the form load for the first time without error. Has anybody found a way around this?Friday, September 5, 2014 4:43 PM
All replies
-
do you mean the early bound classes generated by crmsvcutil.exe?
because in this case they can't be used inside javascript code.
If you are referring to another type of early bound classes (as you call them "early bound javascript classes") please add more details.
My blog: www.crmanswers.net - Rockstar 365 Profile
Friday, September 5, 2014 4:53 PM -
Thanks for the reply.
No, not server-side but client side class generator. I believe this is something fairly new in the SDK for CRM 2013.
-JayB
Friday, September 5, 2014 5:21 PM -
Thanks for the link.
I never used that generator, but because it relies on the sdk.soap library, my best guess (as you already pointed out) is that the generated library is called before the sdk.soap one.
If I have time I will try to play with this generator, meanwhile I suggest to try this approach:
My blog: www.crmanswers.net - Rockstar 365 Profile
Friday, September 5, 2014 5:37 PM -
Thanks, Guido:
I see that by the lack of responses here there will be no solution to this problem that is both simple and elegant. I did enough poking around to find out the problem is quite real. And while resolved initially in CRM 2011 UR13, it was reintroduced at some point in CRM 2013. Particularly frustrating is that Microsoft's own Sdk code (there is even a code generation app, for Pete's sake) will not work out of the box. I was left with the following options:
- Combine all the code I needed into a single Web Resource. While this might be (barely) acceptable if the code were just a one-off for a single form, it is certainly not acceptable if the code is to be reusable. I assume that was the whole point of the Sdk project they gave us.
- I had this idea of dynamically loading the dependent scripts in order using $.getScript(). Foiled again. CRM throws a server error (500) if you try to do this. Not sure why, but I didn't feel like spending the time to find out.
- Create an IFrame that would load resources correctly and provide all my JavaScript Entity access. With all the cross-frame scripting and form changes necessary, this just seems like too much of a kludge. It's probably not worth it.
- Wait for Microsoft to come to their senses and fix this problem (again). Unfortunately I have work to do in the meantime...
- Take your advice and implement the CRM 2011 wait/Timeout code. This seems like such a step backwards. It did lead me to this blog article by Scott Durow. His method of resolving the dependency issue works. I don't particularly like having to duplicate his scriptLoader class on every Web Resource where it needs to be used, but it has to exist and I guess that's the only way to guarantee that it does.
Note to Microsoft: Believe it or not there are dependency injections in JavaScript. Therefore asynchronous is not always better.
Monday, September 8, 2014 6:39 PM -
Sorry to be so late to find this and respond. I wrote the Sdk.Soap.js sample library and the accompanying solution for early bound classes and actions.
I just wanted to say I think your analysis of the issue and possible ways to address this are spot on. I would add that you can also try and mitigate this by not using the early-bound classes and use the late-bound style instead. Early-binding is optional and mostly just improves the developer experience somewhat.
But even using late-bound style is no guarantee. The Sdk.Soap.min.js library is 164kb and you will get this error if you try to use it before it is fully loaded. This is a problem with any library has dependencies on another library.
The purpose of the sample is to demonstrate how a JavaScript library can be prepared to simplify development using the SOAP endpoint. This sample isn't a product feature, just sample code. It provides an alternative to writing special purpose libraries like those we document in the SDK, for example: Walkthrough: Use the Modern app SOAP endpoint with JavaScript. Creating these types of libraries is time consuming, but they do have the advantage that they do not depend on other libraries.
I am also looking forward to this bug in form scripts to be fixed without having to resort to the technique people in the community like Scott Durow have found to work around it. However, I hope the Sdk.Soap.js sample library will be useful for HTML web resource UI, where you have control over the script loading.
Thursday, November 27, 2014 8:02 PM