Getting response with NodeJS request module - json

I just started using the twitch kraken api and I have a few questions.
Whenever I attempt to get a JSON object there is no response. I am attempting to run this function through Amazon AWS Lambda, and don't have access to a console.
In the code below my callback function will always print out "SUCCESS got streamers ERROR". I am pretty certain right now the "ERROR" comes from my initial setting of result.
How come result does not get changed into the proper JSON?
I have used postman and it returns the proper thing with the query and param, and headers:
function getJSON(callback){
var result = "ERROR";
request.get(url(games[0]),function(error,response,body){
console.log("requested for url: " + url(games[0]));
var d = JSON.parse(body);
result = d.streams[0];//.channel.display_name;
// for(var i = 0; i < limit; i++){
// streamers.push(d.streams[i].channel.display_name)
// }
streamers.push(result);
});
if (streamers.length < 0){
callback("ERROR");
}else{
callback("SUCCESS got streamers " + result);
}
}
function url(game){
return {
url: "https://api.twitch.tv/kraken/streams/",//twitchlimit,
qs : {
'game' : 'overwatch',
'limit' : 2
},
headers: {
'Client-ID': clientID,
'Accept': 'application/json',
'Accept-Charset': 'utf-8',
}
};
}

I think your streamers code
if (streamers.length < 0){
callback("ERROR");
}else{
callback("SUCCESS got streamers " + result);
}
should be included in the request callback because currently it's not waiting for the request to finish, it's just carrying on so therefore the value of result will not change. Also the array length cannot be less than 0 so it will always go to the else and say "SUCCESS got streamers ERROR"

Thank you guys for the suggestions. I did have a few oversights and attempted to fix them.
I have implemented you suggestions and it seems to have worked a bit. I ended up putting the json.parse into a try/catch block, and moved the if/else statements inside the getJSON method. However, now I don't get any output.
This is how I am invoking the getJSON method:
function handleGameResponse(intent,session,callback){
//gets the game
var game = intent.slots.game.value;
if (!games.includes(game)){
var speechOutput = "You asked for: " + intent.slots.game.value;
//var speechOutput = "You asked for: " + games[game] + " That game is currently not an option. These are your current options: " + arrayToString(games)
var repromptText = "Please ask one from the current options.";
var header = "Invalid Game";
}else {
getJSON(function(data){
if(data !== "ERROR"){
var speechOutput = data; //capitalizeFirst(game) + " top three streamers are: " + arrayToString(streamers) + '.';
var repromptText = "Do you want to hear more about games?";
var header = capitalizeFirst(game);
}else{
var speechOutput = "I'm sorry, something went wrong and I could not get the streamers.";
}
//speechOutput = data;
});
//speechOutput = games[0] + " games[0], game= " + game; //this executes so the getJSON isn't executing
}
var shouldEndSession = false;
callback(session.attributes,buildSpeechletResponse(header,speechOutput,repromptText,shouldEndSession));
}
Does the above execute the same way? As in the shouldEndSession and callback execute before the getJSON has time to give a response?
For ref, this is the getJSON method now:
function getJSON(callback){
var result = "ERROR";
request.get(url(games[0]),function(error,response,body){
try{
var d = JSON.parse(body);
} catch (err){
callback("Sorry, something seems to have malfunctioned while getting the streamers");
}
result = d.streams[0].channel.display_name;
// for(var i = 0; i < limit; i++){
// streamers.push(d.streams[i].channel.display_name)
// }
streamers.push(result);
if (streamers.length <= 0){
callback("ERROR");
}else{
callback("SUCCESS got streamers " + result);
}
});
}

Related

Connecting Alexa skill to mysql database using node.js and aws lambda

I am trying to connect my Alexa skill to an Amazon RDS mySQL database using node.js in AWS Lambda. I tested the connection before uploading it to lambda and it worked but when I upload it I get a 'process exited before completing request' or a 'There was a problem with the skills response' error.
'use strict';
const Alexa = require('alexa-sdk');
const APP_ID = 'amzn1.ask.skill.11069fc0-53bc-4cd0-8961-dd41e2d812f8';
var testSQL = 'SELECT weight, height from users where pin=1100';
//=========================================================================================================================================
//Database connection settings
//=========================================================================================================================================
var mysql = require('mysql');
var config = require('./config.json');
// Add connection details for dB
var pool = mysql.createPool({
host : config.dbhost,
user : config.dbuser,
password : config.dbpassword,
database : config.dbname
});
// var dbHeight, dbWeight, dbMuscle, dbExerciseOne, dbExerciseTwo, dbExerciseThree, dbExerciseFour;
var dbResult;
function searchDB(quest) {
pool.getConnection(function(err, connection) {
// Use the connection
console.log(quest);
connection.query(quest, function (error, results, fields) {
// And done with the connection.
connection.release();
// Handle error after the release.
if (!!error) {
console.log('error')
}
else {
console.log(results[0]);
dbResult = results[0];
return dbResult;
console.log(dbResult.height);
}
process.exit();
});
});
};
//searchDB(testSQL);
//=========================================================================================================================================
//TODO: The items below this comment need your attention.
//=========================================================================================================================================
const SKILL_NAME = 'My Application';
const GET_FACT_MESSAGE = "Here's your fact: ";
const HELP_MESSAGE = 'You can say tell me a space fact, or, you can say exit... What can I help you with?';
const HELP_REPROMPT = 'What can I help you with?';
const STOP_MESSAGE = 'Goodbye!';
var name, pinNumber;
//=========================================================================================================================================
//Editing anything below this line might break your skill.
//=========================================================================================================================================
const handlers = {
'LaunchRequest': function () {
if(Object.keys(this.attributes).length === 0){
this.attributes.userInfo = {
'userName': '',
'pinNo': 0
}
this.emit('GetPinIntent');
}
else{
name = this.attributes.userInfo.userName;
pinNumber = this.attributes.userInfo.pinNo;
var sql = "";
//var result = searchDB(sql);
//var uWeight = result.weight;
//var uHeight = result.height;
var speechOutput = 'Welcome ' + name + 'Please select an option: Check My BMI, Create Exercise Plan, Create Meal Plan, Update Height and Weight, Update workout status?';
this.emit(':ask', speechOutput);
}
},
'GetPinIntent': function (){
this.emit(':ask','Welcome to my Application, as this is your first time please say your name followed by your pin. For example, my name is Jason and my pin is zero one zero one');
//this.emit(':responseReady');
},
'RememberNameID': function (){
var filledSlots = delegateSlotCollection.call(this);
this.attributes.userInfo.userName = this.event.request.intent.slots.name.value;
this.attributes.userInfo.pinNo = this.event.request.intent.slots.pin.value;
var speechOutput = 'Welcome ' + this.attributes.userInfo.userName + ' we have stored your Pin Number and we will call you by name next time. Please select an option: BMI or exercise';
this.response.speak(speechOutput);
this.emit(':responseReady');
},
'CheckBMI': function(){
var sql = 'SELECT height, weight FROM users WHERE pin=' + this.attributes.userInfo.pinNo;
var heightWeight = searchDB(sql);
dbHeight = parseInt(heightWeight.height);
dbWeight = parseInt(heightWeight.weight);
var speechOutput = bmiCalculator(dbHeight, dbWeight);
this.emit(':ask', speechOutput);
},
'AMAZON.HelpIntent': function () {
const speechOutput = HELP_MESSAGE;
const reprompt = HELP_REPROMPT;
this.response.speak(speechOutput).listen(reprompt);
this.emit(':responseReady');
},
'AMAZON.CancelIntent': function () {
this.response.speak(STOP_MESSAGE);
this.emit(':responseReady');
},
'AMAZON.StopIntent': function () {
this.response.speak(STOP_MESSAGE);
this.emit(':responseReady');
},
'SessionEndedRequest': function() {
console.log('session ended!');
this.emit(':saveState', true);
}
};
exports.handler = function (event, context, callback) {
var alexa = Alexa.handler(event, context, callback);
alexa.APP_ID = APP_ID;
alexa.dynamoDBTableName = 'fitnessDB';
alexa.registerHandlers(handlers);
alexa.execute();
};
function delegateSlotCollection(){
console.log("in delegateSlotCollection");
console.log("current dialogState: "+this.event.request.dialogState);
if (this.event.request.dialogState === "STARTED") {
console.log("in Beginning");
var updatedIntent=this.event.request.intent;
//optionally pre-fill slots: update the intent object with slot values for which
//you have defaults, then return Dialog.Delegate with this updated intent
// in the updatedIntent property
this.emit(":delegate", updatedIntent);
} else if (this.event.request.dialogState !== "COMPLETED") {
console.log("in not completed");
// return a Dialog.Delegate directive with no updatedIntent property.
this.emit(":delegate");
} else {
console.log("in completed");
console.log("returning: "+ JSON.stringify(this.event.request.intent));
// Dialog is now complete and all required slots should be filled,
// so call your normal intent handler.
return this.event.request.intent;
}
};
function bmiCalculator (userHeight, userWeight ) {
var speechOutput = " ";
var h = userHeight/100;
var calcBMI = 0;
calcBMI = userWeight / (h*h);
calcBMI = calcBMI.toFixed(2);
if (calcBMI < 18.5) {
speechOutput += "Based on your weight of " +weight+ " kilograms and your height of " + height + " metres, your BMI is " +calcBMI+ ". Meaning you are currently underweight.";
speechOutput += " I would advise you to increase your calorie intake, whilst remaining active.";
return speechOutput;
}
else if (calcBMI >=18.5 && calcBMI < 25){
speechOutput += "Based on your weight of " +weight+ " kilograms and your height of" + height + " metres, your BMI is " +calcBMI+ ". Meaning you are currently at a normal weight.";
speechOutput += " I would advise you to stay as you are but ensure you keep a healthy diet and lifestyle to avoid falling above or below this.";
this.response.speak(speechOutput);
return speechOutput;
}
else if (calcBMI >=25 && calcBMI < 29.9){
speechOutput += "Based on your weight of " +weight+ " kilograms and your height of" + height + " metres, your BMI is " +calcBMI+ ". Meaning you are currently overweight.";
speechOutput += " I would advise you to exercise more to fall below this range. A healthy BMI is ranged between 18.5 and 24.9";
this.response.speak(speechOutput);
return speechOutput;
}
else{
speechOutput += "Based on your weight of " +weight+ " kilograms and your height of" + height + " metres, your BMI is " +calcBMI+ ". Meaning you are currently obese.";
speechOutput += " I would advise you to reduce your calorie intake, eat more healthy and exercise more. A healthy BMI is ranged between 18.5 and 24.9";
return speechOutput;
}
};
The code outlines my database connection. I created the connection query as a function as I will need to make varying queries to the database based on the context. Is there a way to create a function within the exports.handler function that will only call the query when needed?
Or are there any other solutions with regards to connecting to the database in such a way.
You are running into multiple issues, without using a Promise or await, your call is running async and you will never get an answer immediately from the RDS for the lambda call. you need to create a function that will wait for an answer before continuing its logic.
The other issue you will run into is the MySQL RDS instance is it running constantly there may be a cold start issue.
The last thing is in the AWS lambda console be sure to allocate enough resources in compute and time to run this function the default 128 mb of memory and the time to run the function can be adjusted to improve performance
Use sync-mysql to make synchronous queries to a mysql database. It worked for me.

Catching exceptions thrown by Swagger

I'm new at fumbling with Swagger, so I might be asking a silly question. Is it in any way possible to prevent the site from crashing whenever it is "unable to read from api"?
My site is working most of the time, but if there for some reason is an api that is unreadable (or just unreachable) swagger just stop working. It still displays the api's it managed to reach, but all functionality is completely gone its not even able to expand a row.
To summarize:
How do I prevent swagger from crashing, when one or more API's is unreadable and returns something like this:
Unable to read api 'XXXX' from path
http://example.com/swagger/api-docs/XXXX (server
returned undefined)
Below is my initialization of Swagger:
function loadSwagger() {
window.swaggerUi = new SwaggerUi({
url: "/frameworks/swagger/v1/api.json",
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get', 'post', 'put', 'delete'],
onComplete: function (swaggerApi, swaggerUi) {
log("Loaded SwaggerUI");
if (typeof initOAuth == "function") {
initOAuth({
clientId: "your-client-id",
realm: "your-realms",
appName: "your-app-name"
});
}
$('pre code').each(function (i, e) {
hljs.highlightBlock(e);
});
},
onFailure: function (data) {
log("Unable to Load SwaggerUI");
},
docExpansion: "none",
sorter: "alpha"
});
$('#input_apiKey').change(function () {
var key = $('#input_apiKey')[0].value;
log("key: " + key);
if (key && key.trim() != "") {
log("added key " + key);
window.authorizations.add("api_key", new ApiKeyAuthorization('api_key', key, 'header'));
}
});
$('#apiVersionSelectID').change(function () {
var sel = $('#apiVersionSelectID').val();
window.swaggerUi.url = sel;
$('#input_baseUrl').val(sel);
$('#explore').click();
});
window.swaggerUi.load();
};
I was searching for a solution to this problem too but could not find one. Here is a quick hack i did to solve the problem. Hope it can be of help to someone who is having the same trouble.
In swagger-client.js Find the function error: function (response) {
I replaced the return api_fail with addApiDeclaration to make it draw the api with some limited information even when it fails. I send in a dummy api json object with the path set to "/unable to load ' + _this.url. I send in an extra parameter that can be true or false, where true indicates that this is a failed api.
Old code:
enter cerror: function (response) {
_this.api.resourceCount += 1;
return _this.api.fail('Unable to read api \'' +
_this.name + '\' from path ' + _this.url + ' (server returned ' +response.statusText + ')');
}
New code
error: function (response) {
_this.api.resourceCount += 1;
return _this.addApiDeclaration(JSON.parse('{"apis":[{"path":"/unable to load ' + _this.url + '","operations":[{"nickname":"A","method":" "}]}],"models":{}}'), true);
}
I modified the addApiDeclaration function in the same file to display a different message for a failed api by first adding a secondary parameter to it called failed and then an if statement that check if failed is true and then change the name of the api to "FAILED TO LOAD RESOURCE " + this.name. This adds the FAILED TO LOAD RESOURCE text before the failed api.
Old code
SwaggerResource.prototype.addApiDeclaration = function (response) {
if (typeof response.produces === 'string')
this.produces = response.produces;
if (typeof response.consumes === 'string')
this.consumes = response.consumes;
if ((typeof response.basePath === 'string') && response.basePath.replace(/\s/g, '').length > 0)
this.basePath = response.basePath.indexOf('http') === -1 ? this.getAbsoluteBasePath(response.basePath) : response.basePath;
this.resourcePath = response.resourcePath;
this.addModels(response.models);
if (response.apis) {
for (var i = 0 ; i < response.apis.length; i++) {
var endpoint = response.apis[i];
this.addOperations(endpoint.path, endpoint.operations, response.consumes, response.produces);
}
}
this.api[this.name] = this;
this.ready = true;
if(this.api.resourceCount === this.api.expectedResourceCount)
this.api.finish();
return this;
};
New code
SwaggerResource.prototype.addApiDeclaration = function (response, failed) {
if (typeof response.produces === 'string')
this.produces = response.produces;
if (typeof response.consumes === 'string')
this.consumes = response.consumes;
if ((typeof response.basePath === 'string') && response.basePath.replace(/\s/g, '').length > 0)
this.basePath = response.basePath.indexOf('http') === -1 ? this.getAbsoluteBasePath(response.basePath) : response.basePath;
this.resourcePath = response.resourcePath;
this.addModels(response.models);
if (response.apis) {
for (var i = 0 ; i < response.apis.length; i++) {
var endpoint = response.apis[i];
this.addOperations(endpoint.path, endpoint.operations, response.consumes, response.produces);
}
}
if (failed == true) {
this.name = "FAILED TO LOAD RESOURCE - " + this.name;
}
this.api[this.name] = this;
this.ready = true;
if(this.api.resourceCount === this.api.expectedResourceCount)
this.api.finish();
return this;
};

multiple async mongo request generate messed up returns

I'm trying to build a JSON out of multiple requests on my mongodb.
since I'm not using DBRef, I have to build the "table joints" by myself, and that's how I ended up in this mess.
This is the code that is giving me the headaches from a couple of days now.
(the mongo part is done with mongoskin)
var getUserFeed = function(thelimit, out) {
userfeed = db.collection("userfeed");
apparel = db.collection("apparel");
store = db.collection("stores");
if(thelimit)
args = {limit:thelimit, sort: [['date',-1]]};
userfeed.find({},args).toArray(function(e, feed) {
if (e) console.log("error: ", e);
// gather aparel infos
var i=0;
var ret_feeds = [];
feed.forEach(function(cur_feed) {
var outfits=[];
console.log("beginning with: " + cur_feed.url);
var resfeed = "";
resfeed = cur_feed;
resfeed.url = baseurl + snapurl + resfeed.url + "_small.jpg";
i=0;
cur_feed.apparel_ids.forEach(function(item) {
/*>>*/ apparel.find({"_id": item},{limit:1}).toArray(function(e, results) {
console.log(">>>>>>>>>>> APPAREL_FIND { i:" + i + "}");
if (e) console.log("error: ", e);
results = results[0];
if(results.apparel_cat == 1)
url_subcat = "pants/";
else if(results.apparel_cat == 2)
url_subcat = "shirts/";
else if(results.apparel_cat == 2)
url_subcat = "tshirts/";
results.thumb = baseurl + outfiturl + url_subcat + results.apparel_id + "/front.jpg";
results.size = "M"; ///// TOBE REAL VERY SOON
results.gallery = [
baseurl + outfiturl + url_subcat + results.apparel_id + "/model.jpg",
baseurl + outfiturl + url_subcat + results.apparel_id + "/front.jpg"
];
outfits.push(results); // quick and dirty, 2 b refined..
i++;
if(i>=cur_feed.apparel_ids.length)
{
// pack it up
// resfeed.url = resfeed.url;
resfeed.outfits = outfits;
resfeed.fav = false;
resfeed.bough = false;
// retrieve store infos
/*>>>*/ store.find({"_id":resfeed.store_id}, {limit: 1}).toArray(function(e, resstore) {
console.log("\t############# STORE_FIND { i:" + i + "}");
if (e) console.log("error: ", e);
resfeed.store = resstore[0];
resfeed.store.class = "hem";
ret_feeds.push(resfeed);
if(ret_feeds.length >= feed.length)
{
console.log("\t\t######################calling return [ ret_feeds.length = " + ret_feeds.length + " feed.length = " + feed.length);
out.send(ret_feeds);
}
});
}
});
});
});
});
}
This code fails, because returns the json before finishing its task, so the next time that it tries to return another json it crashes miserably due to the fact the the headers have already been sent.
Now as you can see, I have 3 collections: userfeed, apparel and stores.
the goal of this function is to retrieve all the items in the userfeed collection, extract the outfits (based on the outfit_id array that is part of the userfeed collection), and also extract the store infos related in the same way to each userfeed entry, like so:
I know that async.js or equivalent is the way to go: I've red like a gazillion of other posts here on SO, but I still can't get my head around it, probably because the whole mechanism behind the async.js or flow control in general it's still out of focus in my mind.
I'm still a noob at node :)
UPDATE
I think I found the right path for understanding here: http://www.sebastianseilund.com/nodejs-async-in-practice
this guy made a terrific job in describing use-case by use-case all the ways to apply async.js to your code.
I'll post the solution as soon as I get around it.
UPDATE 2
Thanks to the above dude I could work out a working solution, below is the answer.
After so much struggling I have finally managed to get a solution.
async.js was the answer as I was (obviously) suspecting.
FYI here's the working code.
If you like to point out improvements or anything else, you are more than welcome
var getUserFeed = function(thelimit, out) {
userfeed = db.collection("userfeed");
apparel = db.collection("apparel");
store = db.collection("stores");
var args;
if(thelimit)
args = {limit:thelimit, sort: [['date',-1]]};
var outfits=[];
var feeds = array();
async.series([
// userfeed find
function(callback) {
userfeed.find({},args).toArray(function(e, feed) {
if(e) callback(e);
feeds = array(feed);
console.log(feeds.length + " retrieved. stepping in");
callback(null, null);
});
},
// join
function(callback) {
async.forEach(feeds, function(thefeed, callback) {
var i = feeds.indexOf(thefeed);
async.parallel([
// load apparel infos
function(callback) {
console.log("\t >>> analyzing thefeed id " + thefeed._id);
async.forEach(thefeed.apparel_ids, function(apparel_id, callback) {
apparel.find({"_id": apparel_id},{limit:1}).toArray(function(e, results) {
if (e) console.log("error: ", e);
results = results[0];
if(results.apparel_cat == 1)
url_subcat = "pants/";
else if(results.apparel_cat == 2)
url_subcat = "shirts/";
else if(results.apparel_cat == 2)
url_subcat = "tshirts/";
results.thumb = baseurl + outfiturl + url_subcat + results.apparel_id + "/front.jpg";
results.size = "M"; ///// TOBE REAL VERY SOON
results.gallery = [
baseurl + outfiturl + url_subcat + results.apparel_id + "/model.jpg",
baseurl + outfiturl + url_subcat + results.apparel_id + "/front.jpg"
];
console.log("\t\t### pushing data into thefeed_index: " + i);
if(!util.isArray(feeds[i].oufits)) feeds[i].outfits = array();
feeds[i].outfits.push(results);
callback(null, null);
});
}, callback);
},
// load store infos
function(callback) {
store.find({"_id":thefeed.store_id}, {limit: 1}).toArray(function(e, resstore) {
console.log("\t### STORE_FIND");
if (e) console.log("error: ", e);
feeds[i].store = resstore[0];
feeds[i].store.class = "hem";
callback(null, null);
});
}
], callback);
}, callback);
}
// MAIN
], function(err, result) {
console.log("feed retrieval completed. stepping out");
if (err) return next(err);
out.send(feeds);
});
};

JSON request time out or inconsistent result

I am using JSON and YQL to access some data from an external domain.
http://jsfiddle.net/NdkPU/22/
But the problem I am having is that the code only works intermittently, sometimes I get a response, sometimes nothing is returned.
Obviously this is a very slow solution to access this data - so one reason I thought might be that it is timing out or there is a problem with the callback function.
Any ideas why the result is not working all the time?
// Start function when DOM has completely loaded
$(document).ready(function(){
requestCrossDomain("http://api.fool.com/caps/ws/Ticker/GOOG/Pitches/10?apikey=rW3550aXdsuJPg4bKEemC13x39jDNR6f", function (result) {
var num = 1;
var browserName = navigator.appName;
var doc;
if (browserName == 'Microsoft Internet Explorer') {
doc = new ActiveXObject('Microsoft.XMLDOM');
doc.async = 'false'
doc.loadXML(result.results);
} else {
doc = (new DOMParser()).parseFromString(result.results, 'text/xml');
}
var xml = doc;
console.log("Data Loaded: " + xml);
// Build an HTML string
myHTMLOutput = '';
myHTMLOutput += '<table width="98%" border="1" cellpadding="0" cellspacing="0">';
myHTMLOutput += '<th>Text</th>';
// Run the function for each student tag in the XML file
$('Pitch',xml).each(function(i) {
PitchText = $(this).find("Text").text();
// Build row HTML data and store in string
mydata = BuildStudentHTML(PitchText);
myHTMLOutput = myHTMLOutput + mydata;
});
myHTMLOutput += '</table>';
myHTMLOutput += '<br>Rating: ';
myHTMLOutput += $('Ticker',xml).attr("Percentile");
// Update the DIV called Content Area with the HTML string
$("#ContentArea").append(myHTMLOutput);
});
});
function BuildStudentHTML(PitchText){
// Build HTML string and return
output = '';
output += '<tr>';
output += '<td>'+ PitchText + '</td>';
output += '</tr>';
return output;
}
// Accepts a url and a callback function to run.
function requestCrossDomain(site, callback) {
// If no url was passed, exit.
if (!site) {
alert('No site was passed.');
return false;
}
// Take the provided url, and add it to a YQL query. Make sure you encode it!
var yql = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from xml where url="' + site + '"') + '&format=xml&callback=?';
// Request that YSQL string, and run a callback function.
// Pass a defined function to prevent cache-busting.
$.getJSON(yql, cbFunc);
function cbFunc(data) {
// If we have something to work with...
if (data.results[0]) {
if (typeof callback === 'function') {
callback(data);
}
}
// Else, Maybe we requested a site that doesn't exist, and nothing returned.
else throw new Error('Nothing returned from getJSON.');
}
}
It looks like it's just a slow API. I wrote a simple bash loop that timed that query using curl, and here were the timings:
7.4 sec
11.1 sec
11.2 sec
7.4 sec
11.1 sec
7.3 sec
10.2 sec
11.8 sec
11.3 sec
7.1 sec

Problem in getting right result for select box

I am using jQuery as:
$(document).ready(function(){
test("price");
alert("hi");
$("#item2").change(function()
{
sort= $("#item2").val();
test(sort);
});
});
Function test() is some JavaScript function, my problem is when page loads function calls by "price" parameter. Now when I select some item from select box function test() is called using sort parameter (verify by alert box). but I am not getting the correct result. I mean when I select option from select box than also my result of test() is as with "price" , I suppose it might be the problem because of jQuery's $(document).ready(function(){,. test() function make some html code based on the parameter and show it on the web page.
Please suggest me what can be the solution
EDIT:
function test() is :
function test(sort)
{
<%
Ampliflex ms = Ampliflex.getInstance();
String solrIP = ms.getSolrIP();
String solrPort = ms.getSolrPort();
String rows = ms.getSearchResultCount();
%>
solrIP='<%= solrIP %>'; // get Solr IP address
solrPort='<%= solrPort %>'; // get Solr Port number
rows='<%= rows %>'; // get number of results to return
solrURL="http://"+solrIP+":"+solrPort;
var query="${searchStr}"; // get the query string entered by ECommerce user
query=query.replace(/[^a-zA-Z 0-9*?:.+-^""_]+/g,''); // Remove special characters
query=query.replace(/\*+/g,'*'); // Replace multiple occurrence of "*" with single "*"
var newquery=query;
if(parseInt(query)==NaN)
{
var lowerCaseQuery=query.toLowerCase();
newquery=lowerCaseQuery;
}
else{
var lowerCaseQuery=query;
}
// sort= document.getElementById("item2").value;
$.getJSON(solrURL+"/solr/db/select/?qt=dismax&wt=json&&start=0&rows="+rows+"&q="+lowerCaseQuery+"&hl=true&hl.fl=text&hl.usePhraseHighlighter=true&sort="+sort+" desc&json.wrf=?", function(result){
var highlight = new Array(result.response.numFound);
$.each(result.highlighting, function(i, hitem){
var rg = /<em>(.*?)<\/em>/g;
var res = new Array();
var match = rg.exec(hitem.text[0]);
while(match != null){
res.push(match[1])
match = rg.exec(hitem.text[0]);
}
highlight[i]=res[0]
for (j=1 ;j<res.length;j++)
{
highlight[i]= highlight[i]+","+res[j];
}
});
var html="<table><tr>"
var count=0;
var alt="NoImage";
var size="3pt";
var id;
var flag=1; // Flag for error messages
border="1";
// If no search results
if(result.response.numFound==0)
{
var msg= "<hr /><font size="+size+" >We're sorry, we found no results for <b>"+document.getElementById("queryString").value+"</font><hr />";
}
else
{
/* var msg= "<hr /><font size="+size+" >Total Results Found <b> "+ result.response.numFound+"</b> for "+"<b>"+document.getElementById("queryString").value+"</b> keyword</font><hr /> ";*/
if (newquery==lowerCaseQuery)
{
var msg= "<hr /><font size="+size+" >Total Results Found <b> "+ result.response.numFound+"</b> for "+"<b>"+query+"</b> </font><hr /> ";
}
else
{
var msg= "<hr /><font size="+size+" >There were no exact matches for <b> "+ query+"</b> , so we searched automatically for "+"<b>"+query+"</b> and yielded "+result.response.numFound+" result(s)</font><hr /> ";
}
// Parse solr response and display it on web page
$.each(result.response.docs, function(i,item){
var word = new Array();
word=highlight[item["UID_PK"]].split(",");
var result="";
var j=0;
for (j=0 ;j<=item.text.length;j++)
{
result = result+item.text[j]+"<br>";
}
for (j=0 ;j<word.length;j++)
{
result=result.replace(word[j],'<em>' + word[j] + '</em>');
}
html+="<td><table>";
var src=item.image;
id="id";
if(src!= null && src!= ""){
html+="<p><tr><td><br>"+"<img id= "+id+ " src="+src+ " border="+border+ " /></td></tr>";
count=count+1;
html += "<tr><td><b>ImagePath</b> "+ item.image+"</td></tr>";
}
// If not insert a default image
else
{
src="images/products/default.jpg";
html+="<tr><td><br><p>"+"<img id= "+id+ " src="+src+ " border="+border+" /></td></tr>";
count=count+1;
html += "<tr><td><b>ImagePath</b> "+"No image path found" +"</td></tr>";
}
html += "<tr><td>UID_PK: "+ item.UID_PK+"</td></tr>";
html += "<tr><td>Name: "+ item.name+"</td></tr>";
html+="<tr><td><b>Price: $"+item.price+"</td></tr>";
html+="<tr><td> "+result+"<br></td></tr>";
html+="</p></table></td>"
if(count%3==0)
{
html+="</tr>"
html+="<tr>"
}
});
html+="</table>"
}
$("#text_container").html(msg);
$("#result").append(html);
}
});
});
}
Your question isn't particularly clear, but your alert code only fires when the document is ready - it is not inside the "change" event function.
Try using the following to see what value is being returned when you change the select box:
$(document).ready(function(){
test("price");
$("#item2").change(function()
{
sort= $("#item2").val();
alert(sort);
test(sort);
});
});
When changing the select box, you should get an alert with the value you have chosen, which will help you understand why the test() function isn't functioning as you expect.
If you amend your question to include the HTML of the select box and the test() function itself I will amend my answer to help.
The JQuery code that you have posted is working fine. Demo: http://jsfiddle.net/DtnUr/
We need more details to figure out the issue, such as your HTML code and JS functions.