IE and jQuery posts are not working - javascript

I'm trying to post to my backend with jQuery ajax, and it works in all browsers except internet explorer (ie 11).
Am i missing something for IE?
var example = "example/1234";
jQuery.post('#{test_path}', {
uri: example
}, function(r) {
if (r.status === 201) {
// success
} else {
// failure
}
});
my backed at test_path
def test
render :json => {:status => 401}
end
edit: The code just hangs. The post never reaches my controller, console log remains blank and the network tab doesn't show any post information.

Try putting the uri (a string) as first parameter and not in that object, e. g.:
jQuery.post('/some/uri', {
myPostDataKey: 'myPostDataValue'
}, function(r) {
if (r.status === 201) {
// success
} else {
// failure
}
});

Related

Apply error handling in react google analytics

I am using react-ga (https://www.npmjs.com/package/react-ga) module in my React application, so that i can send events, to google analytics.
I have read the documentation of react-ga and i cant find a way to have a response after i send data to google analytics.
The way i m sending data is like so:
import * ReactGA from 'react-ga'
function sendEvent(category: string, action: string, label: string) {
ReactGA.event({
category,
action,
label,
});
}
function sendPageView(title: string, url: string) {
ReactGA.set({ page: title });
ReactGA.send()
ReactGA.pageview(url);
}
These are just calls to google-analytics, without any feedback, What i m looking for is a function that get a callback OR an async function, that executes the above.
POST request to google-analytics:.
Actually, there is an automatic POST request, each time i m sending an event, which fetches 1 on response.(i dont control the POST request)
The request is like so: Request URL: https://www.google-analytics.com/j/collect?v=1&_v=....
What i try to accomplish, is to catch Errors and send them to Sentry server:.
get errors, in case google analytics server is not responding
get error, in case there is a timeout, on the response of google-analytics.com.
Possibly this module is restricted on functionality, has anyone else used something similar and managed to get any kind of Errors ?
thanks.
I solved the case, based on the official google-analytics documentation: https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#hitCallback
I attach the solutions, for reference:
Send an event and call the callback function when completed:
ReactGA.ga('send', 'event', 'Page view' {
hitCallback: (res: any) => {
console.log('*** page view event success.');
return true;
},
});
Send an event and time it to 1sec.
If the callback is not executed by then, i raise a timeout error, otherwise i execute the success code:
let alreadyCalled: boolean = false;
function myCode(timeout: boolean, hasResponded: boolean) {
if (alreadyCalled) return;
alreadyCalled = true;
if (timeout === true && hasResponded === false) {
// TODO, THROW AN ERROR AND SEND TO SENTRY
console.log('Time out error, sending message to Sentry..');
} else if (timeout === false && hasResponded === true) {
// TODO, send event success
console.log('send event to google-analytics, success');
}
}
ReactGA.ga('send', 'event', 'pageview', { hitCallback: () => myCode(false, true) });
setTimeout(() => myCode(true, false), 10);
I hope it helps anyone that needs something similar.

React concurrent API calls

So, my current code looks something like this:
component:
requestDescriptions(params, bothGender) {
if (bothGender) {
// men request
params.gender = 'men';
this.props.getDescriptions(params);
// women request
params.gender = 'women';
this.props.getDescriptions(params);
} else {
this.props.getDescriptions(params);
}
}
and my action looks like this:
export function getDescriptions(params = { brand: null, category: null, gender: null }) {
return (dispatch) => {
dispatch(requestDescription());
return request
.get(`${getApiUrl()}plp?${QueryString.stringify(params)}`)
.end((err, res) => {
if (err && res.statusCode !== 404) {
...
}
if (res.statusCode === 404) {
// HERE:
console.log(params.gender);
return dispatch(receiveEmptyDescription(params));
}
return dispatch(receiveDescription(res.body));
});
};
}
So up until now, I hadn't noticed the error, but just did when I began testing a scenario where both API calls return a 404.
The error being that having the concurrent calls to the same endpoint is overwriting my params. When the API returns a 200, I could not see the problem. But now when I'm testing returning a 404 I can clearly see the problem.
The problem im getting lies here:
this.props.getDescriptions(params);
params.gender = 'women';
If I check the console log inside my action ( //HERE ) , on both cases params.gender displays 'women' even though the first time around its supposed to be 'men'
I guess this can be fixed using a promise?
Let me know if I'm not clear enough.
The problem isn't really that you're making parallel requests or that you're getting an HTTP2XX or an HTTP4XX.
The reason you are always seeing gender equal to 'women' is that you're using the same object instance for both requests, i.e. params.
What is happening is that you set params.gender to be 'men', fire of the first request, set params.gender to be 'women', fire of the second request.
All the steps above happen synchronously, before any request is completed.
This means that long before any request is finished, params.gender is already equal to 'women'.
Just send a different object to each action.
requestDescriptions(params, bothGender) {
if (bothGender) {
// men request
this.props.getDescriptions({ ...params, gender: 'men' });
// women request
this.props.getDescriptions({ ...params, gender: 'women' });
} else {
this.props.getDescriptions(params);
}
}
Since you're already using Redux, you should be aware that mutation is baaaad 😊

Vuejs won't let me console.log within request

In the methods section of my Vue.js script im trying to do a console.log but nothing is happening, in fact i can do no javascript at all within this section but the request to '/register' remains working.
postRegister: function(){
//code here works fine
console.log('working')
this.$http.post('/register', this.user, function(response){
//Any code here does not work even though the request itself has worked
console.log('not working');
});
}
My Controller
public function Register(Request $request)
{
$validator = Validator::make($request->all(), [
'username' => 'required|unique:users|max:12',
'email' => 'required|unique:users|email',
'password' => 'required|confirmed'
]);
if ($validator->fails()) {
return $validator->errors()->all();
}
}
As i originally said, everything works the validator returns the correct responses and everything and the post attempt is made successfully, there is no console data being logged however within the http post request!
Since you are using the validator you're not getting back a 200 status code and that's why the success function will not get triggered. You should catch the error and then console.log it:
this.$http.post('/register', this.user)
.then(function(response){
console.log(response);
})
.catch(function(error){
console.log(error);
});

Issues retrieving fbsdk Access Token and User ID

I am trying to retrieve the Access Token and User ID of the logged in user in my React Native App. For some reason when I tried to update the fbsdkcore package, it did not exist anymore. So, I tried to resolve it within the general fbsdk package.
I am calling the js file (of which I think retrieves the accesstoken) in the package as:
const AccessToken = require('react-native-fbsdk/js/FBAccessToken');
And subsequently in my code I try to log it so that I can see if it works, simply by:
console.log(AccessToken.getCurrentAccessToken());
console.log(AccessToken.getUserId);
But the log only returns:
2016-05-05 10:22:28.276 [info][tid:com.facebook.React.JavaScript] { _45: 0, _81: 0, _65: null, _54: null }
2016-05-05 10:22:28.277 [info][tid:com.facebook.React.JavaScript] undefined
Which does not seem to be the droids that im looking for.
I inspected the code for the js file in the fbsdk package and the getCurrentAccessToken code looks like this:
/**
* Getter for the access token that is current for the application.
*/
static getCurrentAccessToken(): Promise<?FBAccessToken> {
return new Promise((resolve, reject) => {
AccessToken.getCurrentAccessToken((tokenMap) => {
if (tokenMap) {
resolve(new FBAccessToken(tokenMap));
} else {
resolve(null);
}
});
});
}
Which of course seems reasonable. But since I get this really weird result when I try to call it, I get worried over that I have done something wrong in the bigger picture. I even modified the resolve(null) part of the code so that I could make sure of what happend. But it still returned the same weird "token".
The log also returns this error when logging in:
2016-05-05 10:22:07.630 AppName[15097:415865] -canOpenURL: failed for URL: "fbauth2:/" - error: "(null)"
But I think that is only because I don't have the facebook app on my xcode simulator.
Can anybody throw me a good guess on what I have done wrong??
GetCurrentAccestoken returns a promise.
Maybe you can try:
AccessToken.getCurrentAccessToken().then(
(data) => {
console.log(data.accessToken.toString())
}
)
Try this. It worked for me
AccessToken.getCurrentAccessToken().then(
(data) => {
console.log(data.accessToken)
console.log(data.userID);
});
LoginManager.logInWithReadPermissions(['public_profile']).then(
function (result) {
if (result.isCancelled) {
alert('Login cancelled');
} else {
// alert('Login success with permissions: ' +
// result.grantedPermissions.toString());
AccessToken.getCurrentAccessToken().then(
(data) => {
doLoginViaFb(data.userID, data.accessToken);
}
);
alert(result);
console.log(result.toString());
console.log(JSON.stringify(result));
}
},
function (error) {
alert('Login fail with error: ' + error);
}
);

Chrome Extension - How to get HTTP Response Body?

It seems to be difficult problem (or impossible??).
I want to get and read HTTP Response, caused by HTTP Request in browser, under watching Chrome Extension background script.
We can get HTTP Request Body in this way
chrome.webRequest.onBeforeRequest.addListener(function(data){
// data contains request_body
},{'urls':[]},['requestBody']);
I also checked these stackoverflows
Chrome extensions - Other ways to read response bodies than chrome.devtools.network?
Chrome extension to read HTTP response
Is there any clever way to get HTTP Response Body in Chrome Extension?
I can't find better way then this anwser.
Chrome extension to read HTTP response
The answer told how to get response headers and display in another page.But there is no body info in the response obj(see event-responseReceived). If you want to get response body without another page, try this.
var currentTab;
var version = "1.0";
chrome.tabs.query( //get current Tab
{
currentWindow: true,
active: true
},
function(tabArray) {
currentTab = tabArray[0];
chrome.debugger.attach({ //debug at current tab
tabId: currentTab.id
}, version, onAttach.bind(null, currentTab.id));
}
)
function onAttach(tabId) {
chrome.debugger.sendCommand({ //first enable the Network
tabId: tabId
}, "Network.enable");
chrome.debugger.onEvent.addListener(allEventHandler);
}
function allEventHandler(debuggeeId, message, params) {
if (currentTab.id != debuggeeId.tabId) {
return;
}
if (message == "Network.responseReceived") { //response return
chrome.debugger.sendCommand({
tabId: debuggeeId.tabId
}, "Network.getResponseBody", {
"requestId": params.requestId
}, function(response) {
// you get the response body here!
// you can close the debugger tips by:
chrome.debugger.detach(debuggeeId);
});
}
}
I think it's useful enough for me and you can use chrome.debugger.detach(debuggeeId)to close the ugly tip.
sorry, mabye not helpful... ^ ^
There is now a way in a Chrome Developer Tools extension, and sample code can be seen here: blog post.
In short, here is an adaptation of his sample code:
chrome.devtools.network.onRequestFinished.addListener(request => {
request.getContent((body) => {
if (request.request && request.request.url) {
if (request.request.url.includes('facebook.com')) {
//continue with custom code
var bodyObj = JSON.parse(body);//etc.
}
}
});
});
This is definitely something that is not provided out of the box by the Chrome Extension ecosystem. But, I could find a couple of ways to get around this but both come with their own set of drawbacks.
The first way is:
Use a content script to inject our own custom script.
Use the custom script to extend XHR's native methods to read the response.
Add the response to the web page's DOM inside a hidden (not display: none) element.
Use the content script to read the hidden response.
The second way is to create a DevTools extension which is the only extension that provides an API to read each request.
I have penned down both the methods in a detailed manner in a blog post here.
Let me know if you face any issues! :)
To get a XHR response body you can follow the instructions in this answer.
To get a FETCH response body you can check Solution 3 in this article and also this answer. Both get the response body without using chrome.debugger.
In a nutshell, you need to inject the following function into the page from the content script using the same method used for the XHR requests.
const constantMock = window.fetch;
window.fetch = function() {
return new Promise((resolve, reject) => {
constantMock.apply(this, arguments)
.then((response) => {
if (response) {
response.clone().json() //the response body is a readablestream, which can only be read once. That's why we make a clone here and work with the clone
.then( (json) => {
console.log(json);
//Do whatever you want with the json
resolve(response);
})
.catch((error) => {
console.log(error);
reject(response);
})
}
else {
console.log(arguments);
console.log('Undefined Response!');
reject(response);
}
})
.catch((error) => {
console.log(error);
reject(response);
})
})
}
If response.clone().json() does not work, you can try response.clone().text()
I show my completed code if it can be some help. I added the underscore to get the request url, thanks
//background.js
import _, { map } from 'underscore';
var currentTab;
var version = "1.0";
chrome.tabs.onActivated.addListener(activeTab => {
currentTab&&chrome.debugger.detach({tabId:currentTab.tabId});
currentTab = activeTab;
chrome.debugger.attach({ //debug at current tab
tabId: currentTab.tabId
}, version, onAttach.bind(null, currentTab.tabId));
});
function onAttach(tabId) {
chrome.debugger.sendCommand({ //first enable the Network
tabId: tabId
}, "Network.enable");
chrome.debugger.onEvent.addListener(allEventHandler);
}
function allEventHandler(debuggeeId, message, params) {
if (currentTab.tabId !== debuggeeId.tabId) {
return;
}
if (message === "Network.responseReceived") { //response return
chrome.debugger.sendCommand({
tabId: debuggeeId.tabId
}, "Network.getResponseBody", {
"requestId": params.requestId
//use underscore to add callback a more argument, passing params down to callback
}, _.partial(function(response,params) {
// you get the response body here!
console.log(response.body,params.response.url);
// you can close the debugger tips by:
// chrome.debugger.detach(debuggeeId);
},_,params));
}
}
I also find there is a bug in chrome.debugger.sendCommand. If I have two requests with same URI but different arguments. such as:
requests 1:https://www.example.com/orders-api/search?limit=15&offer=0
requests 2:https://www.example.com/orders-api/search?limit=85&offer=15
The second one will not get the corrected responseBody, it will show:
Chrome Extension: "Unchecked runtime.lastError: {"code":-32000,"message":"No resource with given identifier found"}
But I debugger directly in background devtools, it get the second one right body.
chrome.debugger.sendCommand({tabId:2},"Network.getResponseBody",{requestId:"6932.574"},function(response){console.log(response.body)})
So there is no problem with tabId and requestId.
Then I wrap the chrome.debugger.sendCommand with setTimeout, it will get the first and second responseBody correctly.
if (message === "Network.responseReceived") { //response return
console.log(params.response.url,debuggeeId.tabId,params.requestId)
setTimeout(()=>{
chrome.debugger.sendCommand({
tabId: debuggeeId.tabId
}, "Network.getResponseBody", {
"requestId": params.requestId
//use underscore to add callback a more argument, passing params down to callback
}, _.partial(function(response,params,debuggeeId) {
// you get the response body here!
console.log(response.body,params.response.url);
// you can close the debugger tips by:
// chrome.debugger.detach(debuggeeId);
},_,params,debuggeeId));
},800)
}
I think the setTimeout is not the perfect solution, can some one give help?
thanks.

Categories

Resources