so since Ajax generates something like this for the request
callback=jQuery19104342058659531176
and in the end server returns
jQuery19104342058659531176(data)
what does it call if jQuery19104342058659531176() function is (obviously) not defined?
I understand it will go to success/error handler, but dont really get the purpose of the callback then?
in fact, jQuery will invoke the callback, then invoke success/error.
If you omit "jsonpCallback", then jQuery will invoke the default one deined by jQuery. the source code is in jsonp.js:
window[ callbackName ] = function() {
responseContainer = arguments;
};
Related
I'm trying to sequence my API calls so that I can call an endpoint, wait for it to succeed, then select the required value out of the state.
I'm very new to redux-saga and am finding it difficult to understand how to achieve this!
What I've tried:
So we try and block whilst we perform an API call:
const resp = yield putResolve(assistantActions.fetchSustainability());
Later in the code we select the updated value out of the state:
const assistant = yield select(getAssistant);
The action that is called looks like:
export const fetchSustainability = () => ({ type: FETCH_SUSTAINABILITY });
In the saga we:
yield takeEvery(FETCH_SUSTAINABILITY, fetchSustainability);
Then the function returns a promise:
function fetchSustainability() {
return axios.get(`${url}/sustainability`);
}
I'm not sure that I've set this up any where near right as I've made lots of changes trying to get it working!
The select statement executes immediately and as the call isn't blocked the state isn't updated correctly.
Is my approach correct? If not is someone able to provide a simple working example on how to achieve a blocking call.
So the second parameter to takeEvery needs to be a generator function;
within that you can call your fetchSustainability
function* generator() {
yield call(fetchSustainability); // calls the actual function
}
// in the saga
yield takeEvery(FETCH_SUSTAINABILITY, generator);
your action fetchSustainability should return a Promise.
Here's an example to highlight the difference between put and putResolve.
https://codesandbox.io/s/redux-saga-example-x77jb
The example uses thunkMiddleware
I have a safari extension popover that needs to communicate with its global page. From a content-script I am using
safari.self.tab.dispatchMessage(name,data);
to accomplish that. From a popover I didn't find a way to do that. I know that I can access methods in the global page directly
safari.extension.globalPage.contentWindow
but my goal was to reuse code fragments that are already used in content-scripts. I do the same for the chrome version of the plugin.
Is there code for a little clever proxy that emulates
safari.self.tab.dispatchMessage(name,data);
from the popover?
To be honest it's probably just easier to have different code in your popover and injected scripts. If you really want, you could do something like this:
function dispatchMessage(name, message) {
if (safari.self.tab) {
safari.self.tab.dispatchMessage(name, message);
} else if (safari.extension.globalPage.contentWindow) {
safari.extension.globalPage.contentWindow.handleMessage({name: name, message: message});
}
}
Then just use dispatchMessage('foo', 'bar') in both your popover and injected scripts. It's a bit hacky though, because the message event object normally has more information on it than just the name and message, and you have to ensure that your handleMessage function is actually the same function that is assigned as the message event listener in the global page.
A simplistic way to accomplish reusing your message-based content script code in your popover is by wrapping the safari.self.tab.dispatchMessage calls in an abstraction function that I'll describe below...
But first, you need to make sure to have a single named handler function in your global page that handles all messages, like this:
function handleMessage(evt) {
switch (evt.name) {
case 'Message1':
// do something with evt.message
break;
case 'Message2':
// do something else with evt.message
break;
}
}
safari.application.addEventListener('message', handleMessage, false);
If you have separate handlers for each different message, or if you're using an anonymous function, this approach will not work.
Now, the wrapper function that goes in your popover and content scripts is very simple:
function tellGlobalPage(msgName, msgData) {
if (safari.self instanceof SafariExtensionPopover) {
// this script is running in a popover
var fakeMsgEvt = { name: msgName, message: msgData };
safari.extension.globalPage.contentWindow.handleMessage(fakeMsgEvt);
} else {
// this script is a content script
safari.self.tab.dispatchMessage(msgName, msgData);
}
}
And then instead of safari.self.tab.dispatchMessage(name, data), you use tellGlobalPage(name, data).
Please note that this simplistic approach doesn't deal with roundtrip messaging, where the popover or content script sends a message to the global page, and the global page replies with another message. There are other approaches that can handle that.
So I think I maybe missing something with Ext.Ajax.request();
So I have code that does the following:
Ext.Ajax.request({
url : 'myurl',
success : function(){
alert('success 1');
},
callback : function(){
alert('callback');
}
});
Then later I make another ajax call like this:
Ext.Ajax.request({
url : 'myurl',
success : function(){
alert('success 2');
}
});
If i don't define a callback function the old one from the first call is still set. So when it runs it still calls the old callback function defined earlier. So I add listeners to the
Ext.Ajax.on('beforerequest', function(c, o, e){
//The options has all my previous options
});
So I put a break point in here and looked at the options, and if on my second call or any other ajax call after do not override callback or any other options with an emptyFunction() or any other request config the previous values stays. So if on my second call I didn't redefine the success function the first calls success function would still be there. Is there a way to clear all previous options, on the next call? I could just clear them on each new call. But I don't understand why if the calls are unrelated my options from the last call remain?
As the docs states, Ext.Ajax is a singleton.
If you look at its code, you'll see the the option config will remain between calls.
So I'm afraid to say that you are using it the wrong way. Ideally, you should define what happens upon success or failure with each call.
It does appear though that this will work:
var iAjax = new Ext.data.Connection();
iAjax.request({
// unique config here.
});
[I'm a YUI newbie]
I'm writing a Chrome extension that needs to change the contents of a web page created using the YUI3 framework.
I've identified that the extension, which injects javascript that runs in the page after it is loaded, must call a function that was previously defined in a YUI.add() call.
The original YUI code that runs is something like this:
YUI.add("uuu", function (c) {
...
c.theObject = niceStuff;
}
...
YUI().use("uuu", function (c) {
c.theObject.doSomething();
}
Is it possible that after this code runs, I can access a function of c.theObject?
(I understand this might go against YUI3's nice sandbox mechanism, but it's what I need to get the job done here).
You might have problems because any time a YUI() instance is created, it builds you a new sandbox. With a few exceptions, YUI modules are completely boxed by their sandbox context. For example:
YUI().use('node', function(Y1) {
YUI().use('node', function(Y2) {
assert(Y1.Node === Y2.Node) // fails!
});
});
It's very possible that you may not be able to access the specific instance of theObject that you need, if it's never assigned to a variable outside the sandbox function scope. If any instance of theObject will do, you can just call into the YUI API and get your own version to play with.
This works for me: http://jsfiddle.net/sMAQx/1/
One way to do it is to capture the YUI() instance after you 'use' it. Like this:
YUI().add("uuu", function (c) {
c.theObject = 'foo';
})
var yInstance = YUI().use("uuu", function (c) {
c.theObject = 'booyaa';
})
yInstance.use('uuu',function(c){
console.log(c.theObject)
})
// booyaa
I have 2 dijit widget template classes and am trying to call one from the other but am having issues with dojo.hitch and scope:
I'm in a searchvehicleswidget and call a second widget, commandswidget:
this.CommandsWidget.Post("vehicle/getconfiguration/", request, dojo.hitch(this.CommandsWidget, this.CommandsWidget.FillForms));
Which then calls the Post function in commandswidget:
Post: function(path, request, callbackFunction) {
console.debug("in post");
console.debug(this);
dojo.xhrPost({
url: baseUrl + path,
handleAs: 'json',
timeout: 60000,
content: request,
contentType: "application/x-www-form-urlencoded",
load: dojo.hitch(this, function(result) {
console.debug("in callback function");
console.debug(this);
callbackFunction();
}),
error: function(error, args) { AjaxError(error, args, path, request, callbackFunction); }
});
}
Which then calls the callback function originally passed in, FillForms:
FillForms: function(json) {
console.debug("in fillforms");
console.debug(this);
}
When it calls the Post function, the scope is CommandsWidget, which is correct. Even when we get into the return function for xhrPost load, the scope is still correct, CommandsWidget. However, when I then invoke "callbackFunction();", which calls FillForms(), the scope reverts back to SearchVehiclesWidget! Even if I wrap that call in a dojo.hitch(this, callbackFunction), it still has a scope of SearchVehiclesWidget.
Anyone have any insights into what could be going wrong and how to fix it?
No, CommandsWidget is an instance of the Commands class and SearchVehiclesWidget is an instance of the SearchVehicles class. Yes, FillForms and Post are both in Commands.
I believe, your dojo.hitch is processed at the time of the call to the post function. Meaning the hitch is inside the SearchWidget, and this will reference that. So, the call back function is actually in SearchWidget... (You are passing the function created by dojo.hitch in searchwidget - not a call to dojo.hitch.)
I have noticed DOJO doing stuff like this that was really screwy. I have gone as far as using global variables and being very explicit in the way I call the functions in order to daisy-chain multiple widgets. (Very messy)