answer for "symfony2 chained selectors" not clear - symfony-2.1

I have the same task that described in this topic.
When I am looking in the answer I cant get one thing. What url should be set in the ajax.
$(document).ready(function () {
$('#city_country').change(function(){
$('#city_state option:gt(0)').remove();
if($(this).val()){
$.ajax({
type: "GET",
data: "country_id=" + $(this).val(),
url: Routing.generate('state_list'),
success: function(data){
$('#city_state').append(data);
}
});
}
});
});

You would use a route that points to a controller which accepts a country id and returns a list of state id's within that country.

Related

Chrome Extension - Monitoring network traffic with body data in background [duplicate]

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.

LOADPAGE - Parsing JSON Request failed, status 200

[REGISTER SHIFT/ ASSIGNMENT FORM]
Here is my form, let me describe it; it register next week working hours, I design there are 2 cases: add new and edit in the same form.
When user select an employee, if not register shift yet, we let user register for this employee, if shift is registered already, user can edit in the same form. And I think it will be better not refresh the page, every time user change employee, the form just update and let user add/edit then submit it by post method.
I searched the web, and found a recommendation for ajax/jQuery.
Any more recommendations for me? I've just learn Nodejs/Express with PostgreSQL database.
I am trying to use ajax to load mypage from post event, I call error function in ajax to see what the error is and get:
Parsing JSON Request failed. Status 200.
I'm using NodeJS Express Server, EJS view engine, body-parser, postgresql db.
pool.connect((err, client, release) => {
if (err) {
return console.error('Error acquiring client', err.stack)
}
client.query(
'SELECT * FROM "Employee"', (err, result) => {
release()
if (err) {
res.end();
return console.error('Error executing query', err.stack);
}
console.log(typeof(result));
res.type('json');
res.render("index", {emplist : result});
res.end();
})
})
My ajax function:
$.ajax({
url: "/addshift",
type: "POST",
data: JSON.stringify(employee),
dataType: "application/json",
contentType: 'application/json',
complete: function () {
console.log("go into complete !");
},
success: function (response) {
console.log(response);
console.log("go into success !");
},
error:function(x,e) {
if (x.status==0) {
alert('You are offline!!\n Please Check Your Network.');
} else if(x.status==404) {
alert('Requested URL not found.');
} else if(x.status==500) {
alert('Internel Server Error.');
} else if(e=='parsererror') {
alert('Error.\nParsing JSON Request failed. ' + x.status);
} else if(e=='timeout'){
alert('Request Time out.');
} else {
alert('Unknow Error.\n'+x.responseText);
}
}
});
let's see:
"I am trying to use ajax to load mypage from post event"
Ok, so I suppose you want to get a fully formed HTML page from your $post.
Then, I see:
console.log(typeof(result));
res.type('json');
res.render("index", {emplist : result});
res.end();
res.render will return HTML, this is good for your goal. BUT, you're also specifying a JSON type with res.type. This is causing the error. HTML is not JSON clearly.
Furthermore, you don't need the call to res.end(). res.render() will finish the transaction correctly on its own, res.end is for errors or unexpected conditions.
Your ajax code is ok, but if you're trying to update an html component, like a select, you need to do that manually using the response from ajax, like so:
$("#selectElem").html(response);
Furthermore, you should check your result object from the SELECT * FROM EMPLOYEE query is correctly formatted as proper JSON

How to reload a page with content received by a request made with ajax

I have an ejs file with a list of items from a database. And I'm trying to develop a search which should update this list, only with the results of the search.
I'm sending a post request to the server, by an ajax function from jQuery.
$(".checkbox").on('click', function(){
let email = $(this).find('input').attr('id')
$.ajax({
url: '/dashboard',
method: 'post',
data:{email:email},
success: function(data) {
alert('success')
}
});
})
The post route performs a full search in the database and return a result. Everything is working as it should but the list in my page remains de same, although I'm sending a different json content by the render function.
$text: {
$search: search
},
})
.then(function (results) {
res.render('dashboard', {
name: {},
listagemFuncionarios: results,
check: {}
})
})
.catch(e => console.error(e));
What am I missing here?
The problem is ajax request always get backs the data in the form of json you can not render back a page by requesting through ajax instead you can just get a data back in success in json form and then use it to produce html dynamically through created DOM elements dynamically by Javascript
let suppose you get the data in success function like that
[
{
name:'xyz',
email:'mail#xyz.com'
},
{
name:'xyz',
email:'mail#xyz.com'
}
]
Now you can loop through this data and create html elements let me know if you need more help

Node Jasmine 2.0 and multiple conditions

Jasmine has this funky methodology of not halting at a first failure within a test. This is fine in general, but it doesn't come without issues. I'm wondering what the best practice is for a scenario such as this:
it('should process async results nicely', function (done) {
this.getJSON('something', function(response) {
expect(response.status).toEqual('ok');
expect(response.data).toBeDefined();
expect(response.data.length).toEqual(5);
done();
}
}
The problem here is that this will crash the whole test suite if response.data is undefined. Then again, writing conditionals within a test case is generally frowned upon. Do I have any other choice for this scenario? Given the async nature of most of the tests, this is a very common issue.
If you adhered to OAPT (One Assertion Per Test) you would not have this problem (thought you might have others.)
var resp = null;
beforeEach(function(){
this.getJSON('something', function(response){
resp = response;
});
});
it('should have a defined response', function(){
expect(resp).toBeDefined();
});
it('should have a status of OK:', function(){
expect(resp.status).toEqual('ok');
});
it('should have data:', function(){
expect(resp.data).toBeDefined();
});
it('should have a data length of 5', function(){
expect(resp.data.length).toEqual(5);
});
This probably isn't 100% accurate on how to handle the variable, but it should give you the general idea. If the first one fails (expecting the resp variable to be defined) you know that your .getJSON function is having a problem. This should work because even though a variable is set to null it is still defined. If your function fails, it will set the variable to be undefined, and thus trip the test.
Maybe something like this could do the trick:
it("should make a real AJAX request", function () {
var callback = jasmine.createSpy();
makeAjaxCall(callback);
waitsFor(function() {
return callback.callCount > 0;
}, "The Ajax call timed out.", 5000);
runs(function() {
expect(callback).toHaveBeenCalled();
});
});
function makeAjaxCall(callback) {
$.ajax({
type: "GET",
url: "data.json",
contentType: "application/json; charset=utf-8"
dataType: "json",
success: callback
});
}
Source: http://www.htmlgoodies.com/beyond/javascript/test-asynchronous-methods-using-the-jasmine-runs-and-waitfor-methods.html#fbid=-1PVhTWm6xy
The problem was basically that the errors within an AJAX block got thrown out of the context of the it() block and thus, not being caught. The solution was to write some custom error handling within a function that does the AJAX call and have it succeed or fail with the 'done' passed to the it block.

How to pass value from web service to route and then to database call in Express and NodeJS

I am creating a small project to become familiar with NodeJS, Express and the MEAN stack in general. I'm also very new to web development.
I want to add search functionality to my little site. I have a controller, web service and a javascript file that contains all my database calls (MongoDB).
My question is: How do you pass the search value entered by the user from the web service to the route and then to the db? I've looked everywhere and but I have been unable to find a concrete example. This is what I've got so for.
My controller calls my web service.
this.search = function(searchValue,callback) {
console.log(searchValue);
$http({
method: 'GET',
url: '/contacts/search/:searchValue',
params: {searchValue: searchValue},
headers: {'Content-type': 'application/json'}
}).success(function(resp){
console.log("here");
callback(resp);
}).error(function(){
callback(undefined);
});
};
Next, my web service calls my route...
router.get('/search/:searchValue', function(req, res) {
db.search(req.params.searchValue, function(err,data){
if(!err) {
res.json(data);
}else{
res.json({code:-1,err:err});
}
});
});
Then the database call...
database.prototype.search = function(id,callback){
mongo.connect(dbUrl, function(err, db) {
if(!err) {
db.collection('friends',function(err,coll){
coll.find({friend:"Jimmy"}).toArray(function(err, items) {
db.close();
callback(null,items);
});
});
}else{
db.close();
console.log("hi");
callback(err,null);
}
});
};
Things work fine when I hard code my search value right into my db call (ie. "Jimmy" above). However, I don't know how to pass the search value from my web service to my route and then to the db. I get errors like the route cannot be found or I cannot connect to the database. Silly things that go away when I hard code values.
Anyhow, thank you for your time and patience.
In your router (what you call your web service) you're calling your database search function like this:
router.get('/search/:searchValue', function(req, res) {
db.search(req.params.searchValue, function(err,data){
...
Notice you're passing to your db.search req.params.searchValue
But in your database you have your same search function defined as:
database.prototype.search = function(id, callback){...
which as you can see, takes id as argument.
There's clearly a disconnect here. You're passing it the searchValue from router but you've defined it to take id.
Then further down in database search function you doing this:
database.prototype.search = function(id,callback){
mongo.connect(dbUrl, function(err, db) {
if(!err) {
db.collection('friends',function(err,coll){
coll.find({friend:"Jimmy"}).toArray(function(err, items) {
...
you're calling coll.find to which you should presumably want to pass that searchValue. There's another disconnect here, you're never using the id that you took as a parameter.
If you say that for things to work fine all you gotta do is put "Jimmy", which I guess is the searchValue, then you should try this:
database.prototype.search = function(searchValue,callback){ // replace id with searchValue
mongo.connect(dbUrl, function(err, db) {
if(!err) {
db.collection('friends',function(err,coll){
// use searchValue here
coll.find({friend:searchValue}).toArray(function(err, items) {
...
edit
There's some problem on your client side code as well
$http({
method: 'GET',
url: '/contacts/search/:searchValue',
params: {searchValue: searchValue},
headers: {'Content-type': 'application/json'}
Here you're making an AJAX call with Angular's $http module. And you're making a GET request but you're passing params along with it, which is usually only passed when you make a POST request. Also, the way you've defined your route you're only reading searchValue from the URL itself. So the URL here should be like this:
$http({
method: 'GET',
url: '/contacts/search/' + searchValue,
// params: { no need for params }
...
To explain a bit more how URL params work:
If you request a URL like this
GET /contacts/search/abcd
then you'd define your Express route handler like this
app.get('/contacts/search/:name', function(req, res, next){
req.params.name //=> "abcd"
});
Notice the syntax of route definition /contacts/search/:name is only used for defining the route in Express.
The /:name part is just to assign a variable name - name to the value - "abcd" so it could be accessed as req.params.name
Which is why this is wrong
$http({
method: 'GET',
url: '/contacts/search/:searchValue',
it should be this
$http({
method: 'GET',
url: '/contacts/search/' + yourActualSearchValue,

Resources