_Layout.cshtml:
<script src="#System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/desktop-js-bundle")" type="text/javascript"></script>
Global.asax.cs:
var desktopJsBundle = new Bundle("~/desktop-js-bundle", new CssMinify());
desktopJsBundle.AddFile("~/scripts/jquery-1.7.1.min.js");
BundleTable.Bundles.Add(desktopJsBundle);
When I view source on http://localhost:52221/desktop-js-bundle?v=..., I see the following:
/* Minification failed. Returning unminified contents.
(2,1): run-time error CSS1019: Unexpected token, found '('
(and some other errors like this)
*/
/*! jQuery v.1.7.1 jquery.com | jquery.org/license */
(function(a,b)(function cy(a)....... (the rest of the jquery library. NOTE: starts with that "(")
What am I missing? Does the bundling offered in mvc 4 really not like jquery's way of starting with that "("? Thanks.
UPDATE!
I was using new CssMinify() instead of new JsMinify().
I'm guessing it won't like the missing semicolon of the .min jquery. Try passing in the unminified jquery. On another note, I would not have a bundler/minifier include jquery. You will typically get better perf by going directly to the google or MS CDN since these will likely be pre cached on your viewer's browser.
Related
I am trying to write a unit test where I want to verify that a ajax call has been made.
The code is simple :
it('test spycall',()=>{
spyOn($,"ajax");
//my method call which in turns use ajax
MyFunc();
expect($.ajax.calls.mostRecent().args[0]["url"].toEqual("myurl");
});
The error that I get :
Property 'calls' doesn't exist on type '{settings:jqueryAjaxSettings):jQueryXHR;(url:string, settings?:JQueryAjaxSettings}
$.ajax.calls, among others, is part of the Jasmine testing framework, not JQuery itself (As you know, Jasmine (or rather, Jasmine-Jquery, the plugin you're using) is adding certain debugging functions to JQuery's prototype in order to, well, be able to test ajax calls).
The bad part is that your .d.ts typescript definition file, the file that acts as an interface between typescript and pure JS libraries isn't aware of Jasmine's functions.
There are several ways you could approach fixing this, like
looking if someone has adjusted the JQuery .d.ts file for Jasmine's functions or
creating the new .d.ts file yourself by modifying the original one or, (what I would be doing)
overwriting the typescript definition by declaring $.ajax as any, or not including the typescript definition at all in your testing codebase and declaring $ as any.
There are 2 ways to get rid of the error:
// 1
expect(($.ajax as any).calls.mostRecent().args[0].url).toEqual("myurl");
// 2
let ajaxSpy = spyOn($,"ajax");
expect(ajaxSpy.calls.mostRecent().args[0].url).toEqual("myurl");
You can also use partial matching:
expect(($.ajax as any).calls.mostRecent().args).toEqual([
jasmine.objectContaining({url: "myurl"})
]);
My code:
breeze.config.initializeAdapterInstance("ajax", "angular", true);
...
var ajaxAdapter = breeze.config.getAdapterInstance('ajax');
ajaxAdapter.defaultSettings = {
method: 'POST',
data: {
CompanyName: 'Hilo Hattie',
ContactName: 'Donald',
City: 'Duck',
Country: 'USA',
Phone: '808-234-5678'
}
};
in line 14813 of breeze.debug.js:
ngConfig = core.extend(compositeConfig, ngConfig);
compositeConfig.method has a value of 'POST' until it is overwritten, because ngConfig.method has a value of 'GET'.
I imagine this question is relevant for any ajax setting, but of course I'm mainly struggling with how to post with the angular ajax adapter, so maybe there's an entirely better way to do that? this approach feels dirty anyway, but breeze.ajaxPost.js only works with the jQuery ajax adapter, right?
6 Oct 2014 update
We recently had reason to revisit ajaxpost and have updated both the code and the documentation.
The original recommendation works. We're merely clarifying and updating the happy path.
A few points:
The ajaxpost plug-in works for both jQuery and Angular ajax adapters.
Those adapters long ago became aware of adapter.defaultSettings.headers and have blended them into your Breeze ajaxpost http calls (take heed, PW Kad).
You must call breeze.ajaxPost() explicitly after replacing the default ajax adapter as you do when you use the 'breeze.angular' service.
You can wrap a particular ajax adapter explicitly: breeze.ajaxPost(myAjaxAdapter); We just don't do that ourselves because, in our experience, it is sufficient to omit the params (breeze.ajaxPost()) and let the method find-and-wrap whatever is the active ajax adapter of the moment.
The documentation explains the Angular use case which I repeat here to spare you some time:
// app module definition
var app = angular.module('app', ['breeze.angular']); // add other dependencies
// this data service abstraction definition function injects the 'breeze.angular' service
// which configures breeze for angular use including choosing $http as the ajax adapter
app.factory('datacontext', ['breeze', function (breeze) { // probably inject other stuff too
breeze.ajaxPost(); // wraps the now-current $http adapter
//... your service logic
}]);
Original reply
AHA! Thanks for the plunker (and the clever use of the Todo-Angular sample's reset method!).
In brief, the actual problem is that breeze.ajaxpost.js extends the jQuery ajax adapter, not the angular ajax adapter. There is a timing problem.
The root cause is that you can't tell breeze.ajaxpost.js which adapter to wrap. It always wraps the default adapter at the time that it runs. As you've got your script loading now, the jQuery adapter is the current one when breeze.ajaxpost.js runs.
The workaround is to set the default adapter to the angular adapter before breeze.ajaxpost.js runs.
One way to do that is to load the scripts as follows ... adding an inline script to set the default ajax adapter to the "angular" version.
<script src="breeze.debug.js"></script>
<script>
<!-- Establish that we will use the angular ajax adapter BEFORE breeze.ajaxpost.js wraps it! -->
breeze.config.initializeAdapterInstance("ajax", "angular", true);
</script>
<script src="breeze.ajaxpost.js"></script>
Clearly this is a hack. We'll look into how we can change breeze.ajaxpost.js so you can wrap any ajax adapter at the time of your convenience.
Thanks for finding this issue, and thanks Ward for bringing it to my attention. I've updated the breeze.ajaxpost.js code to use .data as you described, and added a function you can call after adapter initialization. So now you can do:
var ajaxAdapter = breeze.config.initializeAdapterInstance("ajax", "angular");
ajaxAdapter.setHttp($http);
breeze.ajaxpost.configAjaxAdapter(ajaxAdapter); // now we can use POST
So, it's slightly less hacky.
This answer is applicable to the following plugins and version:
Breeze.Angular v.0.8.7
Breeze.AjaxPost v.1.0.6
I just saw a new plugin called Breeze.Angular.js that can work in conjunction with Breeze.AjaxPost.js
You have to modify the Breeze.AjaxPost.js in order for it to work. Breeze.Angular.js initializes your adapter when your page loads, and Breeze.AjaxPost.js will take in the adapter initialized from Breeze.Angular.js
You can learn more about the Breeze.Angular server here: breeze-angular-service
You can learn more about Breeze.Ajaxpost here: breeze-ajaxpost
Now to set this up wasn't exactly apparent, because I took both files exactly as they were in git.
1.) Reference the files in this order:
<script src="Scripts/q.min.js"></script>
<script src="Scripts/breeze.angular.js"></script>
<script src="Scripts/breeze.ajaxpost.js"></script>
2.) Go into your breeze.ajaxpost.js
Remove this line (or comment this line):
breeze.ajaxpost(); // run it immediately on whatever is the current ajax adapter
The reason why is because, this will cause your ajaxpost method to run before your breeze.angular service. When you go into the ajaxpost method, the ajaxAdapter parameter that is supposed to be passed in will be null. Removing this line appends the functionality for later in your code, so you can call it from the breeze.angular service.
3.) In breeze.angular.js go to your useNgHttp method. It should look like this:
// configure breeze to use Angular's $http ajax adapter
var ajaxAdapter = breeze.config.initializeAdapterInstance("ajax", "angular");
ajaxAdapter.setHttp($http);
breeze.ajaxpost(ajaxAdapter); // now we can use POST
When you run your program, both plugins should be able to set up the environment for you without having to include it in every javascript that makes your calls to the webapi.
Thanks guys for the plugins.
I am trying to implement a custom web resource using jquery/ajax and odata. I ran into trouble and eventually found that when I call:
var serverUrl = context.getServerUrl();
The code throws exceptions.
However, when I change serverUrl to the literal url, it works. I then found forum posts that said I should verify my .aspx page manually by going to https://[org url]//WebResources/ClientGlobalContext.js.aspx to verify that it is working. When I did that I received a warning page:
The XML page cannot be displayed
Cannot view XML input using style sheet. Please correct the error and then click the Refresh button, or try again later.
--------------------------------------------------------------------------------
Invalid at the top level of the document. Error processing resource 'https://[org url]//WebResources/Clien...
document.write('<script type="text/javascript" src="'+'\x26\x2347\x3b_common\x26\x2347\x3bglobal.ashx\x26\x2363\x3bver\x2...
What the heck does that mean?
Hard to tell outside of context (pun not intended) of your code, but why aren't you doing this?
var serverUrl = Xrm.Page.context.getServerUrl();
(Presumably, because you have defined your own context var?)
Also, this method is deprecated as of Rollup 12, see here: http://msdn.microsoft.com/en-us/library/d7d0b052-abca-4f81-9b86-0b9dc5e62a66. You can now use getClientUrl instead.
I now it is late but hope this will be useful for other people who will face this problem.
Until nowadays even with R15 there are two available ClientGlobalContext.js.aspx
https://[org url]/WebResources/ClientGlobalContext.js.aspx (the bad one)
https://[org url]/[organization name]/[publication id]/WebResources/ClientGlobalContext.js.aspx (The good one)
I don't know why exist 1. but it causes many issues like:
It could not be published or hold information (Your case #Steve).
In a deployment with multiple organizations, seems it saves info only for the last organization deployed causing that methods under Xrm.Page.context. will return info from a fixed organization. Actually each method that underground uses these constants included in ClientGlobalContext.js.aspx: USER_GUID, ORG_LANGUAGE_CODE, ORG_UNIQUE_NAME, SERVER_URL, USER_LANGUAGE_CODE, USER_ROLES, CRM2007_WEBSERVICE_NS, CRM2007_CORETYPES_NS, AUTHENTICATION_TYPE, CURRENT_THEME_TYPE, CURRENT_WEB_THEME, IS_OUTLOOK_CLIENT, IS_OUTLOOK_LAPTOP_CLIENT, IS_OUTLOOK_14_CLIENT, IS_ONLINE, LOCID_UNRECOGNIZE_DOTC, EDIT_PRELOAD, WEB_SERVER_HOST, WEB_SERVER_PORT, IS_PATHBASEDURLS, LOCID_UNRECOGNIZE_DOTC, EDIT_PRELOAD, WEB_RESOURCE_ORG_VERSION_NUMBER, YAMMER_IS_INSTALLED, YAMMER_IS_CONFIGURED_FOR_ORG, YAMMER_APP_ID, YAMMER_NETWORK_NAME, YAMMER_GROUP_ID, YAMMER_TOKEN_EXPIRED, YAMMER_IS_CONFIGURED_FOR_USER, YAMMER_HAS_CONFIGURE_PRIVILEGE, YAMMER_POST_METHOD. For instance method Xrm.Page.context.getUserId() is implemented as return window.USER_GUID;
To be sure that your URL is the correct just follow the link posted by #Chris
I'm trying to use iChemLabs cloud services from a html5 web worker. Normally the cloudservices requires jQuery but I can't import that into a web worker so I'm using Pollen instead with a ChemDoodle Web Components library with which I have stripped out the document-related things.
jQuery.Hive.Pollen provides a nice ajax function very similar to jQuery, but I can't seem to get it to work at all. I know this problem will be tricky to solve considering that Access-control-headers need to be set to allow any of you to actually find the solution. However, I'm a beginning javascript programmer and I was wondering if my two weeks of frustration is actually a small difference. I am trying to invoke the following function:
var cloudmolecule;
ChemDoodle.iChemLabs.readSMILES('N1(C)C(=O)N(C)C(C(=C1N1)N(C=1)C)=O', function(mol){
cloudmolecule = mol;
});
Here is a link to the library code I am using, see the 'q.ajax' call and substitute jQuery = q for p = q (p is for pollen) in that block of code.
Right now I'm just trying to get the ajax call to work in an ordinary block of javascript with the plan to migrate to a web worker later.
If anybody could point out the problem to me I would be extremely grateful.
solved! turns out iChemLabs rejects these two extra headers that pollen creates:
_xhr.setRequestHeader("X-Requested-With", "Worker-XMLHttpRequest");
_xhr.setRequestHeader("X-Worker-Hive", "Pollen-JS" );
Simply comment them out
Also, Pollen ajax seems to return a JSON object containing the data in JSON format AND as a string, so do
o = JSON.parse(data.string)//data is the parameter to the callback function
The reduced ChemDoodle library (without document-related methods) will work like a charm with pollen ajax.
I understand this question has been asked multiple times on various sites and forums however the context has mostly been jquery. In my case, I am not using jquery at all though I am using CakePHP 1.3 with prototype and scriptoculous. I am trying to make Ajax pagination work using default Js helper however every time I load the page, I get the error below in error console
Error: $(document).ready is not a function
Any idea what's wrong here.
It seems (after some googeling) that the syntax to use in prototype is document.observe('dom:loaded', fn);
http://www.prototypejs.org/api/document/observe
In prototype, I think you can use
document.observe("dom:loaded", function() {
// Do initialization here
});
for performing the initialization tasks.