Error calling JavaScript from Java - javascript

I'm trying to call JavaScript in a JavaFx WebView from Java, but I get:
Exception in thread "JavaFX Application Thread" netscape.javascript.JSException: TypeError: undefined is not a function
at com.sun.webkit.dom.JSObject.fwkMakeException(JSObject.java:128)
at com.sun.webkit.WebPage.twkExecuteScript(Native Method)
at com.sun.webkit.WebPage.executeScript(WebPage.java:1439)
at javafx.scene.web.WebEngine.executeScript(WebEngine.java:982)
.java file
private WebView emailSubject() {
String pageURL = "D:myproject\\src\\resources\\WEB_INF\\forms\\readMail\\emailBody.html";
pageURL = pageURL.replace("\\", "/");
webView = new WebView();
webView.setMaxHeight(52);
webEngine = webView.getEngine();
emailSubject = getHTMLMailSubject();
webEngine.getLoadWorker().stateProperty().addListener((ov, oldState, newState) -> {
if (newState == State.SUCCEEDED) {
webEngine.executeScript("testCheckMate(\"" + emailSubject + "\");");
}
});
webEngine.load("file:" + pageURL);
return webView;
}
Exception which points to this line:
webEngine.executeScript("testCheckMate(\"" + emailSubject + "\");");
The HTML:
<!-- Latest compiled and minified JavaScript -->
<script src="../../baseJS/JQuery/jquery-1.11.3.js"></script>
<script src="../../baseJS/JQuery/jquery.min.js"></script>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">Home Alone</h3>
</div>
</div>
<script>
$(document).ready(function() {
window.testCheckMate = function (data) {
$(".panel-title" ).append(data);
};
});
</script>
What am I doing wrong? Thank you all in advance.
Please note that I've tried:
load(); already
$(".panel-title" ).load(data);
as well as with
testCheckMate outside $(document).ready(function(), but still nothing.
testCheckMate = function (data) {
$(".panel-title" ).load(data);
};

Related

Decoding/Debugging stripe.js: The value of the property 'Stripe' is null or undefined, not a Function object

I'm following the stripe server integration guide here. My server creates a stripe session, and returns:
<HTML lang=en><HEAD><TITLE>Payments</TITLE></HEAD>
<BODY>
<H1>Loading.....</H1>
loading stripe
<SCRIPT src="https://js.stripe.com/v3/"></SCRIPT>
done loading stripe
<SCRIPT type=text/javascript>
try {
document.writeln('creating Stripe object');
// error occurs here, Stripe is undefined
var stripe = Stripe('<PUBLIC KEY GOES HERE>');
document.writeln('redirecting to checkout');
stripe.redirectToCheckout({
sessionId: '<SESSION ID GOES HERE>'
}).then(function (result) {
});
document.writeln('done calling javascript');
}
catch(error) {
document.writeln('error occurred: ' + error.message);
}
</SCRIPT>
<H1>....DONE</H1></BODY></HTML>
NOTE: the public key and session id have been redacted
This works fine when loaded by firefox/ie explorer, but when using wxWidgets Webview which uses ie explorer as it's backend it throws
The value of the property 'Stripe' is null or undefined, not a
Function object
wxpython webview code:
import wx, traceback
from wx.html2 import WebView, EVT_WEBVIEW_ERROR, EVT_WEBVIEW_LOADED, EVT_WEBVIEW_NAVIGATING, EVT_WEBVIEW_NEWWINDOW, \
WEBVIEWIE_EMU_IE11
html = """<HTML lang=en><HEAD><TITLE>Payments</TITLE></HEAD>
<BODY>
<H1>Loading.....</H1>
loading stripe
<SCRIPT src="https://js.stripe.com/v3/"></SCRIPT>
done loading stripe
<SCRIPT type=text/javascript>
try {
document.writeln('creating Stripe object');
// error occurs here, Stripe is undefined
var stripe = Stripe('<PUBLIC KEY GOES HERE>');
document.writeln('redirecting to checkout');
stripe.redirectToCheckout({
sessionId: '<SESSION ID GOES HERE>'
}).then(function (result) {
});
document.writeln('done calling javascript');
}
catch(error) {
document.writeln('error occurred: ' + error.message);
}
</SCRIPT>
<H1>....DONE</H1></BODY></HTML> """
class Main(wx.Frame):
def __init__(self):
super().__init__(parent=None, size=(1000, 800))
self._times_loaded = 0
self.webview = WebView.New(self) # type: WebView
self.webview.Bind(EVT_WEBVIEW_ERROR, self.on_error)
self.webview.Bind(EVT_WEBVIEW_LOADED, self.on_loaded)
self.webview.Bind(EVT_WEBVIEW_NAVIGATING, self.on_navigate)
self.webview.Bind(EVT_WEBVIEW_NEWWINDOW, self.on_new_window)
# wx.CallAfter(self.load_gateway)
wx.CallAfter(self.load_html)
self.Show()
# def load_gateway(self, evt=None):
# self.webview.LoadURL(url)
def load_html(self):
self.webview.SetPage(html, "www.stripe.com")
def reset_page(self):
self.webview.SetPage(self.webview.GetPageSource(), url)
# def redirect_to_checkout(self):
# # stripe.
# session= stripe.checkout.session.Session.create(test_stripe_public_key)
def on_error(self, evt):
print(f"error occurred: {evt}")
def on_navigate(self, evt):
print("on navigate")
def on_loaded(self, evt):
print("loaded")
self._times_loaded += 1
def on_new_window(self, evt):
print("new window event")
try:
app = wx.App()
frame = Main()
app.MainLoop()
except:
input(traceback.format_exc())
For some reason the first script at https://js.stripe.com/v3/ doesn't create the Stripe object when called with the ie explorer emulator.
I assumed it was an issue with an unsupported user-agent so I replaced all user-Agent references in the stripe script with
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
which didn't work. I tried to read through https://js.stripe.com/v3/ to see why Stripe would be undefined. My javascript skills are pretty weak and it is clearly minified/obfuscated so I'm having a difficult time understanding how and why Stripe would be undefined. It looks like it's declared dynamically, but what about the emulated browser is causing it to be undefined?
--------------Update 9-23-19---------------
After #duck suggested it might be a problem with my script running before the stripe script was loaded I changed the html to sequence the redirect function to run after stripe was loaded:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Payments</title>
</head>
<body>
<script type="text/javascript">
function redirectToCheckout(evt){
try {
document.writeln('loading stripe.js')
var stripe = Stripe('REDACTED');
document.writeln('redirecting to checkout');
stripe.redirectToCheckout({
sessionId: 'REDACTED'
}).then(function (result) {
});
document.writeln('done calling javascript');
}
catch(error) {
document.writeln('error occurred: ' + error.message);
}
}
//source: https://stackoverflow.com/questions/950087/how-do-i-include-a-javascript-file-in-another-javascript-file
function loadScript(url, callback)
{
// Adding the script tag to the head as suggested before
//document.writeln('loading stripe script');
console.log('loading stripe script');
var head = document.head;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = callback;
script.onload = callback;
// Fire the loading
head.appendChild(script);
}
function loadStripe(evt){
loadScript('https://js.stripe.com/v3/', redirectToCheckout);
}
var onloadScript = loadStripe;
if(window.attachEvent) {
window.attachEvent('onload', onloadScript);
} else {
if(window.onload) {
var curronload = window.onload;
var newonload = function(evt) {
curronload(evt);
onloadScript(evt);
};
window.onload = newonload;
} else {
window.onload = onloadScript;
}
}
</script>
Page loaded
</body>
</html>

Could not find property of window when doing JS interop with Blazor

Hello i am trying to call a method from a js file from Blazor.
My file structure is like this:
-root
-JSInterop.cs
-js(folder)
-meth.js (file containing the js method)
I keep getting the following error :
Could not find 'methods' in 'window'.
**Cs class that calls the js **
public class JSInterop {
public static async Task<string> ChangeText() {
try {
var data = await JSRuntime.Current.InvokeAsync<string>("./js/meth/methods.print","mymessage");
Console.WriteLine($"ReturnedFromJS:{data}");
return data;
} catch (Exception ex) {
return ex.Message;
}
}
}
Js file
function print(message){
return "fromJs"+message;
}
window.methods = {
print: function (message) {
return "from js" + message;
}
}
I have tried both putting just the method and putting it as a property in the window.I am not sure in the first case how do you refer a method from a file in js.
"[path to file]/[containingfile]/[methodname]" ?
or i have also tried "[path to file] / window.[methodname]"
to no avail (in the second case)
Index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width">
<title>Sms.Studio.Web</title>
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/site.css" rel="stylesheet" />
</head>
<body>
<app>Loading...</app>
<!-- browser -->
<script src="_framework/blazor.webassembly.js"></script>
<script src="../interop/js/meth.js"></script>
</body>
</html>
JSRuntime.Current.InvokeAsync takes a js function identifier relative to the global window scope as its first argument. So in your js file you may have :
window.methods = {
print: function (message) {
return "from js" + message
}
Add your js file in index.html
<script src="css/bootstrap/bootstrap-native.min.js"></script>
<script src="_framework/blazor.webassembly.js"></script>
<script src="js/meth.js"></script>
and call it from .Net as follows
await JSRuntime.Current.InvokeAsync<string>("methods.print","mymessage");
// Try this:
// Don't call your class JSInterop
public class MyJSInterop {
public static async Task<string> ChangeText() {
try {
var data = await JSRuntime.Current.InvokeAsync<string>("methods.print","mymessage");
Console.WriteLine($"ReturnedFromJS:{data}");
return data;
} catch (Exception ex) {
return ex.Message;
}
}
}
// Js file
window.methods = {
print: function (message) {
return "from js" + message;
}
};
Below is an end to end example of writing cookie.
step 1 - Add MatButton and sets it onClick attribute to delegate.
<MatButton TrailingIcon="favorite" #onclick="#(async () => await AddItemtoShoppingCart(#item))" Label="add"></MatButton>
Step 2
#code{
public async Task AddItemtoShoppingCart(FoodItem selectedItem)
{
var test = await JSRuntime.InvokeAsync<object>("blazorExtensions.WriteCookie", "cookieName", "cookieValue", "cookieExpiryDate");
}
}
Step 3 - Add below javasceipt in_Host.cshtml
<script>
window.blazorExtensions = {
WriteCookie: function (name, value, days) {
var expires;
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toGMTString();
}
else {
expires = "";
}
document.cookie = name + "=" + value + expires + "; path=/";
}
}
</script>

How to connect signalR from angularJs

I am developing web application in .NET as two separate applications, back end using webapi c# and user interface using AngularJS. I just want to add Chat option in this project. I have installed SignalR and added ChatHub.cs class in webapi.
enter image description here
in WebAPI there is a class named Startup.cs
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local;
WebApiConfig.Register(config);
app.UseCors(CorsOptions.AllowAll);
ConfigureAuth(app);
app.UseWebApi(config);
app.MapSignalR();//added after installation of SignalR package
}
}
ChatHub class
public class ChatHub : Hub
{
public static string emailIDLoaded = "";
public void Connect(string userName, string email)
{
emailIDLoaded = email;
var id = Context.ConnectionId;
using (SmartCampEntities dc = new SmartCampEntities())
{
var userdetails = new ChatUserDetail
{
ConnectionId = id,
UserName = userName,
EmailID = email
};
dc.ChatUserDetails.Add(userdetails);
dc.SaveChanges();
}
}
}
Whatever request i send from user interface it will hit to its corresponding controller in webAPI. For example
$http({
method: 'GET',
url: $scope.appPath + "DashboardNew/staffSummary" //[RoutePrefix]/[Route]
}).success(function (result, status) {
data = result;
});
My user interface is a separate application. How can i connect signalR from UI.
I tried something but didn't get it work. Can anyone suggest me how to get it work
html code
<div>
<a class="btn btn-blue" ng-click="sendTask()">SendTask</a>
javascript
angular.module('WebUI').controller('DashboardCtrl', function ($scope, $window, $http, $modal, ngTableParams) {
$scope.header = "Chat";
$scope.sendTask = function () {
$http({
method: 'POST',
url: $scope.appPath + hubConnetion.server.sendTask("userName","email"),
})
}
});
Basics:
That you can connect to your signalr server you have to include the client code to your page. It's also important that you include jquery before.
At least you can also include the generate hubs file in the case you are working with hubs:
<script src="Scripts/jquery-1.10.2.min.js"></script>
<script src="Scripts/jquery.signalR-2.1.0.min.js"></script>
<script src="signalr/hubs"></script>
Basic Sample:
Here you have a full sample (without and with generated hub proxy):
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<div class="container">
<div class="row">
<!-- Title -->
<h1>SignalR Sample</h1>
</div>
<div class="row">
<!-- Input /Button-->
<input type="text" id="inputMsg" />
<button button="btn btn-default" id="btnSend">Send</button>
</div>
<div class="row">
<!-- Message list-->
<ul id="msgList"></ul>
</div>
</div>
<script src="Scripts/jquery-1.6.4.js"></script>
<script src="Scripts/jquery.signalR-2.2.0.js"></script>
<script src="http://[LOCATIONOF YOUR HUB]/signalr/hubs"></script>
<script>
// ------------------- Generated Proxy ----------------------------
$(function () {
$.connection.hub.url = "[LOCATION WHERE YOUR SERVICE IS RUNNING]/signalr";
var chat = $.connection.myChat;
chat.client.addMessage = function (name, message) {
$('#msgList').append('<li><strong>' + name
+ '</strong>: ' + message + '</li>');
};
$.connection.hub.start({}).done(function () {
$('#btnSend').click(function () {
chat.server.Send("Stephan", $('#inputMsg').val());
$('#inputMsg').val('').focus();
});
})
});
//// ------------------- Without Proxy ----------------------------
//$(function () {
// var connection = $.hubConnection("http://localhost:8080/signalr");
// var chatHubProxy = connection.createHubProxy('chatHub');
// chatHubProxy.on('AddMessage', function (name, message) {
// console.log(name + ' ' + message);
// $('#msgList').append('<li><strong>' + name
// + '</strong>: ' + message + '</li>');
// });
// connection.start().done(function () {
// $('#btnSend').click(function () {
// chatHubProxy.invoke('send', "Stephan", $('#inputMsg').val());
// $('#inputMsg').val('').focus();
// });
// });
//});
</script>
</body>
</html>
For more details see:
http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client
SignalR Angular Module:
There is also a "helper module" which you can use in angularjs for working with signalr:
https://github.com/JustMaier/angular-signalr-hub
I can able to connect webapi by adding below code into my Startup.Auth.cs
public void ConfigureAuth(IAppBuilder app)
{
app.UseOAuthBearerTokens(OAuthOptions);
//by adding below code
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR(new HubConfiguration { EnableJSONP = true });
}

How to show json data into html <ul><li></li></ul> tag using jquery in asp.net

I am working on asp.net application where i am trying to fetch data from database in JSON format and display that JSON data into html-ul-li tag using jquery. My Html Page is:
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script language="javascript" type="text/javascript">
//function GetCompanies() {
$(document).ready(function () {
$.ajax({
type: "POST",
url: "MobileServices.asmx/BindCategory",
data: "{}",
dataType: "json",
contentType: "application/json; charset=utf-8",
async: true,
success: OnSuccess,
error: OnError
});
function OnSuccess(data) {
$.each(data, function (key, value{
$("#ulCategory").append("<li><a rel=external href=Category_News.html?ID=" + value.Category_ID + ">" + value.Category_Name + "</li>");
})
}
function OnError(data) {
}
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<ul id="ulCategory">
</ul>
</div>
</form>
</body>
</html>
My WebService to Access the Data is :
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.Services;
using Newtonsoft.Json;
using System.Configuration;
namespace MobileNewsAppication
{
/// <summary>
/// Summary description for MobileServices
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class MobileServices : System.Web.Services.WebService
{
public class NewsCategory
{
public long Category_ID { get; set; }
public string Category_Name { get; set; }
public string QFlag { get; set; }
}
[WebMethod]
public string BindAllCategory()
{
DataTable dt = new DataTable();
//List<NewsCategory> details = new List<NewsCategory>();
using (SqlConnection con = new SqlConnection(Connection))
{
SqlCommand cmd = new SqlCommand("AllCategory_Select", con);
cmd.CommandType = CommandType.StoredProcedure;
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
return JsonConvert.SerializeObject(dt);
}
}
}
}
But the the ul Tag is not binding any list item inside. I think foreach loop defined inside jquery OnSuccess method may be wrong. Please help me.
If this isn't a typo here then it's a syntax error causing the success callback to fail...
function OnSuccess(data) {
// $.each(data, function (key, value{ <- this is wrong
$.each(data, function() {
$("#ulCategory").append("<li><a rel='external' href='Category_News.html?ID=" + this.Category_ID + "'>" + this.Category_Name + "</li>");
});
}
Try using this inside each instead. I also wrapped the link attributes in quotes. Other than that it looks fine to me. If that isn't the issue then put console.log(data); as the 1st line of the success callback and check the console for that and any errors.

Implementing WebSockets using SignalR

I'm trying to use websockets into my ASP.NET MVC web-app but I can't implement, so here I'm trying to display each database update on the end-user web-page without any need to refresh.
HTML:
<span id="nbAlertes"></span>
<ul id="listeAlertes"></ul>
Javascript / SignalR / jQuery
<!--Reference the SignalR library. -->
<script src="Scripts/jquery.signalR-2.0.2.min.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="signalr/hubs"></script>
<script>
$(function () {
// Declare a proxy to reference the hub.
var alertes = $.connection.AlerteHub;
// Create a function that the hub can call to broadcast messages.
alertes.client.broadcastMessage = function (nbAlertes, listeAlertes) {
// Html encode display name and message.
var nbA = $('<div />').text(nbAlertes).html();
var lstA = $('<div />').text(listeAlertes).html();
// Add the message to the page.
$('#nbAlertes').text(nbA);
lstA.forEach(function(item) {
$('#listeAlerte').append(item.nomPoste);
});
};
});
</script>
class AlerteHub:
public class AlerteHub : Hub
{
public void GetAll()
{
var nbAlertes = new CalculAlertesUtilitaire().compter();
var listeAlertes = new CalculAlertesUtilitaire().lister(5);
// Call the broadcastMessage method to update clients.
Clients.All.broadcastMessage(nbAlertes, listeAlertes);
}
MonitoringNDataContext _db = new MonitoringNDataContext();
public string compter()
{
var compte = _db.Alertes.ToList().Count();
return (compte == 0) ? "" : compte.ToString();
}
public ICollection<AlerteModel> lister(int nb)
{
return (ICollection<AlerteModel>)_db.Alertes.ToList().Take(nb).ToArray();
}
}
class Startup
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Any connection or hub wire up and configuration should go here
app.MapSignalR();
}
}
How do I to make it work, please ?
If you want to use SignalR, you need to establish the connection on the client. In JavaScript you do this by calling connection.start(). For example:
<!--Reference the SignalR library. -->
<script src="/Scripts/jquery.signalR-2.0.2.min.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="/signalr/hubs"></script>
<script>
$(function () {
// Declare a proxy to reference the hub.
var alertes = $.connection.alerteHub;
// Create a function that the hub can call to broadcast messages.
alertes.client.broadcastMessage = function (nbAlertes, listeAlertes) {
// Html encode display name and message.
var nbA = $('<div />').text(nbAlertes).html();
var lstA = $('<div />').text(listeAlertes).html();
// Add the message to the page.
$('#nbAlertes').text(nbA);
lstA.forEach(function(item) {
$('#listeAlerte').append(item.nomPoste);
});
};
$.connection.hub.start().done(function () {
// You should probably be calling GetAll from somewhere.
// I'm not sure if you should call it as soon as you connect,
// but you certainly can't call GetAll before connecting.
alertes.server.getAll();
}).fail(function (error) {
alert("Failed to connect!");
});
});
</script>
You can learn more about how to use the Signalr JS client here: http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-javascript-client

Categories