.NET AJAX asynchronous calls - javascript

I've been tasked with including asynchronous calls to my webpage and I'm not sure where to start. Currently, my webpage takes user input from a drop down list, converts it into a list of CodeDesc objects, serializes it all into JSON and then deserializes it back so it can be displayed in a GridView on the screen. (I could just make it spit out the CodeDesc object back to the GridView but this is the way my manager wanted it so..).
In any case, now I need the results to be displayed without reloading the page and after some research I read that AJAX was a good way to do it. Unfortunately, I'm confused how I can connect it all and actually use it. My attempts are below but I could really use some guidance on the matter.
HTML (partial):
<script>
$("#Button1").on("click", function () {
$.ajax({
type: ??'GET'??,
contentType: ??
success: function (?? Call deserializeJSONResults function ??) {
$('#GridView2').html("");
for (var i = 0; i < deserializedProduct.length; i++) {
$("#GridView2").append(deserializedProduct.id, deserializedProduct.code, deserializedProduct.);
}
}
});
});</script>
Without using AJAX my code is below:
CS:
protected void Button1_Click(object sender, EventArgs e)
{
DataConnector dc = new DataConnector();
GridView2.DataSource = dc.deserializeJSONResults(DropDownList1.SelectedValue);
GridView2.DataBind();
}
Backend:
//Return results to GridView2 as list of CodeDesc objects
public List<CodeDesc> getQueryResults(string searchTerm)
{
try
{
List<CodeDesc> L = new List<CodeDesc>();
string query = "select id, code, descr from code_desc where code_type_id = (select id from code_desc where descr = :searchTerm)";
// Create the OracleCommand
using (OracleCommand cmd = new OracleCommand(query, con))
{
cmd.Parameters.Add(new OracleParameter("searchTerm", searchTerm));
con.Open();
// Execute command, create OracleDataReader object
using (OracleDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
CodeDesc c = new CodeDesc
{
id = reader.GetInt32(0),
code = reader.GetString(1),
description = reader.GetString(2)
};
L.Add(c);
}
}
}
return L;
}
//catch clause here
}
//Convert to JSON and parse
public List<CodeDesc> deserializeJSONResults(string searchTerm)
{
List<CodeDesc> L = getQueryResults(searchTerm);
string json = JsonConvert.SerializeObject(L, Formatting.Indented);
//deserialize object
List<CodeDesc> deserializedProduct = JsonConvert.DeserializeObject<List<CodeDesc>>(json);
return deserializedProduct;
}
}
Any help would be appreciated. I have little development experience and this is my first time with web/.NET development

Related

Javascript receiving Resource object containing chars instead of String

My Java code should return user login as a String, but on Javascript side I'm receiving a strange Resource object whose numbered attributes each contains one char.
Here is my Java code:
#PostMapping(path = "/account/reset_password/finish", produces = MediaType.TEXT_PLAIN_VALUE)
#Timed
public ResponseEntity<String> finishPasswordReset(#RequestBody KeyAndPasswordVM keyAndPassword) {
if (!checkPasswordLength(keyAndPassword.getNewPassword())) {
return new ResponseEntity<>("Incorrect password", HttpStatus.BAD_REQUEST);
}
return userService.completePasswordReset(keyAndPassword.getNewPassword(), keyAndPassword.getKey()).map(
user -> new ResponseEntity<String>(user.getLogin(), HttpStatus.OK)).orElse(
new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
}
Javascript controller code:
Auth.resetPasswordFinish({key: $stateParams.key, newPassword: vm.resetAccount.password}).then(function (userLogin) {
vm.success = 'OK';
console.log("userLogin="+userLogin);
}).catch(function () {
vm.success = null;
vm.error = 'ERROR';
});
The console prints:
userLogin=[object Object]
which is not very interesting.
Inspecting the received object gives:
One can see that each char of the String is a numbered attribute of the Resource object.
Javascript Auth code:
function resetPasswordFinish (keyAndPassword, callback) {
var cb = callback || angular.noop;
return PasswordResetFinish.save(keyAndPassword, function (userLogin) {
return cb(userLogin);
}, function (err) {
return cb(err);
}).$promise;
}
This one is just passing the parameter to the callback function.
Do you know how to receive a plain String instead of this Resource object? I apologize if this is a trivial question.
I know that doing this will work in order to retrieve the user login:
var i = 0;
var userLoginToString = "";
while (typeof userLogin[String(i)] !== 'undefined') {
userLoginToString += String(userLogin[String(i)]);
i += 1;
}
however I don't think that this is the intended way to use this Resource object.

How to establish a click listener in a separate class from the event Vaadin

I am very new to Vaadin and v-Leaflet. I have created a component that takes some geojson data and puts it over a map. I am able to click on any of the polygons/ multi polygons and get back a few bits of information in the form of a notification. The thing is, I need to take this information and click event and have it influence about 4 other separate components in their own separate classes. I have been racking my brain with this for the past 2 days and just can't seem to grasp it.
Here is my map/ click event:
private LMap map;
String filePath = this.getClass().getResource("/fccpeasgeo.json").getPath();
File file = new File(filePath);
//ArrayList<String> peaNames = new ArrayList<String>();
//#Override
public LMap createMap() {
map = new LMap();
FeatureJSON io = new FeatureJSON();
try {
long currentTimeMillis = System.currentTimeMillis();
// Look ma, no proxy needed, how cool is that!
FeatureCollection fc = io.readFeatureCollection(file);
Logger.getLogger(LeafletMap.class.getName()).severe("Download in " + (System.currentTimeMillis() - currentTimeMillis));
currentTimeMillis = System.currentTimeMillis();
FeatureIterator iterator = fc.features();
try {
while (iterator.hasNext()) {
Feature feature = iterator.next();
final String name = feature.getProperty("PEA_Name").getValue().toString();
final String population = feature.getProperty("POPs_2010").getValue().toString();
Geometry geometry = (Geometry) feature.getDefaultGeometryProperty().getValue();
// The geojson provided in example is rather complex (several megabytes)
// Use JTS to simplyfy. Note that it is rather easy to use
// different settings on different zoom levels, as well as decide
// to drop the feature form client altogether
geometry = DouglasPeuckerSimplifier.simplify(geometry, 0.2);
// In this example can be Polygon/Multipolygon
Collection<LeafletLayer> toLayers = JTSUtil.toLayers(geometry);
for (LeafletLayer l : toLayers) {
map.addComponent(l);
if (l instanceof LPolygon) {
LPolygon lPolygon = (LPolygon) l;
lPolygon.addClickListener(new LeafletClickListener() {
#Override
public void onClick(LeafletClickEvent event) {
Notification.show("PEA: " + name + " Population: " + population);
}
});
}
}
}
Logger.getLogger(LeafletMap.class.getName()).severe("Reducing and creating layers " + (System.currentTimeMillis() - currentTimeMillis));
} finally {
iterator.close();
}
} catch (MalformedURLException ex) {
Logger.getLogger(LeafletMap.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(LeafletMap.class.getName()).log(Level.SEVERE, null, ex);
}
map.zoomToContent();
//map.setCenter(40, -95.2);
//map.setZoomLevel(2.5);
LTileLayer tf = new LTileLayer();
tf.setUrl("http://{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png");
tf.setSubDomains(new String[]{"a", "b", "c"});
tf.setActive(true);
map.addBaseLayer(tf, "ThunderForest Transport");
return map;
}
Here is one of the components that will be receiving the event.
public Chart mhzPerSqMile() {
Chart chart = new Chart();
run();
chart.setCaption("Total MHz Per Square Mile");
chart.getConfiguration().setTitle("");
chart.getConfiguration().getChart().setType(ChartType.PIE);
chart.getConfiguration().getChart().setAnimation(false);
chart.setWidth("100%");
chart.setHeight("90%");
DataSeries series = new DataSeries();
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName()!=null)
{
if (evt.getPropertyName().equals("abcTask"))
{
}
}
for (int i = 0; i < 5; i++) {
Operator operator = operators.get(i);
if (selectedPea != null) {
if (operator.getPeaName().toLowerCase() == selectedPea.toLowerCase()){
DataSeriesItem item = new DataSeriesItem(operator.getName(),
operator.getTotalMHzSqMile());
series.add(item);
item.setColor(DummyDataGenerator.chartColors[i]);
}
}
}
chart.getConfiguration().setSeries(series);
PlotOptionsPie opts = new PlotOptionsPie();
opts.setBorderWidth(0);
opts.setShadow(false);
opts.setAnimation(false);
chart.getConfiguration().setPlotOptions(opts);
Credits c = new Credits("");
chart.getConfiguration().setCredits(c);
return chart;
}
}
}
Any advice would be very appreciated!
what I think you simply need to fire a property with any specific name (Event name) and all your listener classes have implemented PropertyChangeListener which triggers on every fireProperty() call , obviously you are matching your event name there and hence all you 4 classes perform their task upon receiving such a property change
You need to register PropertyChangeSupport for current instance
PropertyChangeSupport pcs = new PropertyChangeSupport(this);
further you'll use this object to fire your event
Firing event
//this firing code will probably go inside your click method that actually causes an event to occur
pcs.firePropertyChange("abcTask", oldValue, newValue);
Recieving event
#Override
public void propertyChange(PropertyChangeEvent evt)
{
if (evt.getPropertyName()!=null)
{
if (evt.getPropertyName().equals("abcTask"))
{
//perform task
}
}
}

Facebook Javascript API call to me/invitable_friends returns only 25 results on cordova but not on web

I'm developing a game on cordova that uses facebook integration. I have a facebook game canvas running on a secure site.
The friend request works fine on the web site version (returns more than 25 results, as I'm iterating the paging.next url that is also returned).
However, on the cordova build (android) it only ever returns the first result set of 25. It does still have the page.next url JSON field but it just returns a response object with a type=website.
Has anyone else come across this?
After quite a lot of digging I found an issue with the way requests are handled in the FacebookLib for Android. The current version of the com.phonegap.plugins.facebookconnect plugin uses Android FacebookSDK 3.21.1 so I'm not sure if this will still be an issue with v4.
A graph result with a paging url is used to request the next page however using the entire url, which includes the https://graph.facebook.com/ as well as the usual graphAction causes an incorrect result set to be returned. However I determined that if you remove the schema and host parts it will be correct.
I modified the ConnectPlugin.java to check that any schema and host is removed from the graphAction. Seems to work well now.
ConnectPlugin.java before:
private void makeGraphCall() {
Session session = Session.getActiveSession();
Request.Callback graphCallback = new Request.Callback() {
#Override
public void onCompleted(Response response) {
if (graphContext != null) {
if (response.getError() != null) {
graphContext.error(getFacebookRequestErrorResponse(response.getError()));
} else {
GraphObject graphObject = response.getGraphObject();
JSONObject innerObject = graphObject.getInnerJSONObject();
graphContext.success(innerObject);
}
graphPath = null;
graphContext = null;
}
}
};
//If you're using the paging URLs they will be URLEncoded, let's decode them.
try {
graphPath = URLDecoder.decode(graphPath, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String[] urlParts = graphPath.split("\\?");
String graphAction = urlParts[0];
Request graphRequest = Request.newGraphPathRequest(null, graphAction, graphCallback);
Bundle params = graphRequest.getParameters();
if (urlParts.length > 1) {
String[] queries = urlParts[1].split("&");
for (String query : queries) {
int splitPoint = query.indexOf("=");
if (splitPoint > 0) {
String key = query.substring(0, splitPoint);
String value = query.substring(splitPoint + 1, query.length());
params.putString(key, value);
if (key.equals("access_token")) {
if (value.equals(session.getAccessToken())) {
Log.d(TAG, "access_token URL: " + value);
Log.d(TAG, "access_token SESSION: " + session.getAccessToken());
}
}
}
}
}
params.putString("access_token", session.getAccessToken());
graphRequest.setParameters(params);
graphRequest.executeAsync();
}
ConnectPlugin.java after:
private void makeGraphCall() {
Session session = Session.getActiveSession();
Request.Callback graphCallback = new Request.Callback() {
#Override
public void onCompleted(Response response) {
if (graphContext != null) {
if (response.getError() != null) {
graphContext.error(getFacebookRequestErrorResponse(response.getError()));
} else {
GraphObject graphObject = response.getGraphObject();
JSONObject innerObject = graphObject.getInnerJSONObject();
graphContext.success(innerObject);
}
graphPath = null;
graphContext = null;
}
}
};
//If you're using the paging URLs they will be URLEncoded, let's decode them.
try {
graphPath = URLDecoder.decode(graphPath, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String[] urlParts = graphPath.split("\\?");
String graphAction = urlParts[0];
///////////////////////
// SECTION ADDED
///////////////////////
final String GRAPH_BASE_URL = "https://graph.facebook.com/";
if(graphAction.indexOf(GRAPH_BASE_URL)==0) {
URL graphUrl = null;
try {
graphUrl = new URL(graphAction);
} catch (MalformedURLException e) {
e.printStackTrace();
}
graphAction = graphUrl.getPath();
}
///////////////////////
// END SECTION ADDED
///////////////////////
Request graphRequest = Request.newGraphPathRequest(null, graphAction, graphCallback);
Bundle params = graphRequest.getParameters();
if (urlParts.length > 1) {
String[] queries = urlParts[1].split("&");
for (String query : queries) {
int splitPoint = query.indexOf("=");
if (splitPoint > 0) {
String key = query.substring(0, splitPoint);
String value = query.substring(splitPoint + 1, query.length());
params.putString(key, value);
if (key.equals("access_token")) {
if (value.equals(session.getAccessToken())) {
Log.d(TAG, "access_token URL: " + value);
Log.d(TAG, "access_token SESSION: " + session.getAccessToken());
}
}
}
}
}
params.putString("access_token", session.getAccessToken());
graphRequest.setParameters(params);
graphRequest.executeAsync();
}
There's no way to know that you call their api from cordova vs website, so it's some problem on your side, maybe you use some different implementation of the api on corodva and website, so that cordova sends a pagination request or send to other api version which does pagination.

Reference controls within web service?

I have an onBlur() function in a textbox which calls a web service.
The web service checks the email entered in the textbox against a SQL table to see if it's in there and if it is, I need it to deactivate an ASP Button. (Plus a bit more fiddly stuff, but once I crack the button all should be well). However, whenever I try to reference the button control (or any other ASP control) inside the web service I am treated to an error "Cannot refer to an instance member of a class from with a shared method..."
How can I disable a button & change a panel's visibility from the web service?
onBlur()
In VB.net
txtEmail.Attributes.Add("onblur", CStr(IIf(c.AccountNo > 0, "", "CallMe(this.id,this.id);")))
In Jscript.js file
//AJAX Call to server side code
function CallMe(src, dest) {
aForgotPwd.style.display = 'none';
var ctrl = document.getElementById(src);
var cont = document.getElementById(btn);
var panel = document.getElementById(pnl);
// call server side method
return PageMethods.ValidateEmail(ctrl.value, CallSuccess, CallFailed, dest);
}
// set the destination textbox value with the ContactName
function CallSuccess(res, destCtrl) {
var dest = document.getElementById(destCtrl);
if (res == "") {
if(aForgotPwd.style.display != 'none')
{ aForgotPwd.style.display = 'none'; }
return true;
} else {
setTimeout("aForgotPwd.style.display='block';", 1);
setTimeout("dest.focus();", 1);
setTimeout("dest.select();", 1);
alert("We have your email address already in our database. Please visit forgot your password page");
return false;
}
//alert(res.get_message());
// var dest = document.getElementById(destCtrl);
}
// alert message on some failure
function CallFailed(res, destCtrl) {
var dest = document.getElementById(destCtrl);
return true;
}
Web Service called by CallMe() function
'Email Validation
<System.Web.Services.WebMethod()> _
Public Shared Function ValidateEmail(email As String) As String
Dim wbClient As WebClient = New WebClient()
Dim strUrl As String = ConfigurationManager.AppSettings("WebsiteURLFull") + "/ajax/check_email_address.aspx?Email=" + email
Dim reqHTML As Byte()
reqHTML = wbClient.DownloadData(strUrl)
Dim objUTF8 As UTF8Encoding = New UTF8Encoding()
Dim output As String = objUTF8.GetString(reqHTML)
If String.IsNullOrEmpty(output) Then
exists = False
Else
exists = True
btnContinue.enabled = False
End If
If String.IsNullOrEmpty(output) Then Return String.Empty
Dim c As GPCUser
If TypeOf HttpContext.Current.Session("Customer") Is GPCUser Then
c = CType(HttpContext.Current.Session("Customer"), GPCUser)
If c.AccountNo > 0 Then Return ""
End If
Return output
End Function
You cannot acces page objects in the web service method, rather you can disable the button and the visibility of the panel post the execution of the webservice in your call back function. Just return a message from your method which says email already present or new. Let me know if I am unclear.
EDIT
You can find further details of the webmethod implementation in this link https://msdn.microsoft.com/en-us/library/byxd99hx(v=vs.90).aspx
<System.Web.Services.WebMethod(EnableSession:=True)> _
Public Shared Function ValidateEmail(email As String) As String
Dim wbClient As WebClient = New WebClient()
Dim strUrl As String = ConfigurationManager.AppSettings("WebsiteURLFull") + "/ajax/check_email_address.aspx?Email=" + email
Dim reqHTML As Byte()
reqHTML = wbClient.DownloadData(strUrl)
Dim objUTF8 As UTF8Encoding = New UTF8Encoding()
Dim output As String = objUTF8.GetString(reqHTML)
If String.IsNullOrEmpty(output) Then
exists = False
Else
exists = True
'btnContinue.enabled = False
'Commenting the Button enabling
output="disable"
'Assinging the output as disable so that in JS you can disable btn
End If
If String.IsNullOrEmpty(output) Then Return String.Empty
Dim c As GPCUser
If TypeOf HttpContext.Current.Session("Customer") Is GPCUser Then
c = CType(HttpContext.Current.Session("Customer"), GPCUser)
If c.AccountNo > 0 Then Return ""
End If
Return output
End Function
Also now in the CallSuccess before you continue with your functionality check whether the res is disable then you can disable button and display the already existing message.

how to bind the list to dropdownlist in javascript?

I am calling a web method from a JavaScript function
function loadstatecity() {
alert(document.getElementById("CountryList").value);
// PageMethods.username_availability(document.getElementById("CountryList").value, OnSuccess, OnFailure);
PageMethods.loadstatecity(document.getElementById("CountryList").value, OnSuccess,OnFailure);
}
Web method is returning a list of strings:
[System.Web.Services.WebMethod]
public static List<string> loadstatecity(string countrycode)
{
utilityFunc.loadstatecity(countrycode);
return utilityFunc.state;
}
loadstatecity function Code:
public static void loadstatecity(string CountryCode)
{
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["Mag_SDK"].ConnectionString))
{
con.Open();
using (SqlCommand com = con.CreateCommand())
{
com.CommandText = "Select ProvinceName from Province where CountryCode=#Country ;";
com.Parameters.AddWithValue("#country", CountryCode);
SqlDataReader dr = com.ExecuteReader();
while (!dr.Read())
{
state.Add(dr["ProvinceName"].ToString());
}
com.Connection.Close();
com.Connection.Dispose();
}
con.Close();
}
}
Now I want to bind this list to a DropDownList.
How can I do this?
Thank you for your help.
The List of strings type returned in your C# method will be serialized into a JavaScript array and will be accessible in a JavaScript callback. You'll then need to loop through all of the strings in the serialized array converting each one to an HTML 'option' element and then attach each element to the HTML 'state' select element produced by your ASP.NET. Here's some code which should accomplish that:
// The function to run on success, adds options to the state select.
function success(response) {
var select = document.getElementById('id-of-your-state-select-element'),
index = 0,
option = ''
value = '';
if (select) {
for (index; index < response.length; index++) {
value = response[index];
option = '<option>' + value + '</option>';
select.insertAdjacentHTML('beforeend', option);
}
}
}
// Shows an error in an alert box, should be improved before
// production deployment.
function error(response) {
alert(response);
}
These two functions are then used in your 'loadstatecity' method as success / failure callbacks.
PageMethods.loadstatecity(document.getElementById("CountryList").value, success, error);

Categories