Please have a look at the JavaScript code below.
const locations = /*[[${locations}]]*/ null;
locations.forEach(location => {
location.description = 44;
location.lnglat = 127;
location.fun(); // error
});
description and lnglat are variables from Java list of objects of class 'Location'; fun is a function from this class.
There is no problem assigning values to variables, but I can't call the function fun. Unfortunately, I don't know what the reason is and how can I fix it.
In Java, I use Spring Boot and method addAttribute:
#GetMapping("/")
public String homePage(Model model) {
model.addAttribute("locations", locations());
return "home";
}
Related
I am working on a small project that will primarily be a C# library. I also want to create a JavaScript counterpart that is functionally equivalent. I would like to be able to test both from the same unit tests.
To be clear I am NOT going to be using this in a production environment where C# calls JS, or vice versa. I only want to blend C# and JavaScript in the context of the unit tests so I can verify and maintain cross-platform compatibility. Most examples I find show that this is possible within Blazor using JSRuntime, but I don't want to do this within a web application.
Below is an example of what I am trying to accomplish.
C# Method:
public class CsharpLibrary
{
public static bool CheckLength(string str) {
if (str.Length > 10)
return false;
return true;
}
}
JavaScript Function:
function CheckLength(str) {
if (str.length > 10)
return false;
return true;
}
Unit Test
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace CsharpJavascriptUnitTesting
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void CheckLength_TooLong()
{
var str = "1234567890123456789";
var isValid = CsharpLibrary.CheckLength(str);
Assert.IsFalse(isValid);
// TODO: is it possible to load the local Javascript file?
// TODO: call JavaScript CheckLength(str);
// TODO: assert that the value returned is also false
}
}
}
Thanks to the recommendation in the comment above from Collen I was able to accomplish this with the Jurassic library.
[TestMethod]
public void CheckLength_TooLong()
{
var str = "1234567890123456789";
var isValid = CsharpLibrary.CheckLength(str);
Assert.IsFalse(isValid);
var engine = new Jurassic.ScriptEngine();
engine.ExecuteFile(#"..\..\JsLibrary.js");
isValid = engine.CallGlobalFunction<bool>("CheckLength", str);
Assert.IsFalse(isValid);
}
I have been told my function:
for (const key of Object.keys(temp)) {
this.sessionData.push(temp[key]);
}
Must now use a .map instead,
I have tried this below:
Object.keys(temp).map(function(key) {
this.sessionData[key];
})
But 1 I don't know if it's actually accurate, and also, it cant access the data outside of the scope of the function it is in, here is the whole function below:
public sessionData;
sessionDates(sessionsData) {
const temp = {};
this.sessionData = [];
sessionsData.forEach(session => {
const date = moment(session.startDatetime).format('DDMMYYYY');
if (temp[date]) {
temp[date].push(session);
} else {
temp[date] = [session];
}
});
Object.keys(temp).map(function(key) {
this.sessionData[key];
})
TRYING TO USE THIS BELOW... session data is undefined, it can't access out of the scope?
Object.keys(temp).map(function(key) {
this.sessionData[key];
})
But this works..
for (const key of Object.keys(temp)) {
this.sessionData.push(temp[key]);
}
So this new .map method can't access anything out of its scope.. sigh!
If anybody can help that would be amazing! Thanks!
In Javascript all functions can access variables from outside (called "higher scope") - it's one of the strengths of the language and is called "capture".
The reason your code is failing is because it's using this.sessionData inside a function declaration, which cases problems because this in javascript is... somewhat complex. But you don't need it!
You also need to make sure you return the value you want to output. Here's how I would write it:
this.sessionData = Object.keys(temp).map(key => temp[key]);
I imagine it would look like the following.
Server(C#):
public class MyHub : Hub {
...
public int DoSomething(Func<int> fn) {
var res = fn();
return res;
}
...
}
Client(TS/JS):
myHub.invoke('DoSomething', () => 2 + 2).then(res => console.log(res));
However, with this code fn is null on the server.
Seems this is impossible as your parameters should be serializable. So all you can - serialize parameters in known structure and generate invocation function based on deserialization result.
You could write the function in c# and pass it back to the server as a string, then compile and run it - this might help with compiling:
http://www.codeproject.com/Tips/715891/Compiling-Csharp-Code-at-Runtime
I am trying to structurise JS code using Revealing Prototype Pattern.
My basic usecase is: Create different types of entities like Person, Technology. Each entity has its own tags. In order to get these tags i make an ajax call which returns an object of tags. I want to access this object in my implementation. But i am not sure how to do it in right way.
My attempt is as follows:
var Entity= function (url) {
this.url = url; /*variable that can be shared by all instances*/
var entityTags;
};
Entity.prototype = function () {
var create = function (type, values) {
//code for creating
}
var update = function (type, values) {}
var tags = function () {
AjaxCall(' ', this.url, {data:data}, 'callbackAfterGetTags', '');
callbackAfterGetTags=function(responseFromAjax)
{
entityTags=responseFromAjax.tagsReturned; //how to access this entityTags in my implementation
}
};
return {
createEntity: create,
getTagsEntity: tags
};
My Implementation
var myEntity = new Entity(url);
myEntity.getTagsEntity();
Ajax call returns object successfully but i am not sure how to access the object inside tags functions in a right way. Any suggestions? This is my first trial to use OO style in JS. Let me also know if i am right track or not.
This seems like a very basic question. But how do I create a class structure within Google Apps Script?
Lets say I want to call: myLibrary.Statistics.StandardDeviation(). I have to instead call: myLibrary.StandardDeviation().
I cannot seem to break it down any further, or organize it into classes.
How can I do this?
I suspect there's something more that you're not telling us about your situation. It is possible to set up a function as a property of an object that is itself a property of an object, and thus support the calling structure you've described.
function test() {
Logger.log( myLibrary.Statistics.StandardDeviation([5.3,5.2,5,2.0,3.4,6,8.0]) ); // 1.76021798279042
};
myLibrary.gs
var myLibrary = {};
myLibrary.Statistics = {}
myLibrary.Statistics.StandardDeviation = function( array ) {
// adapted from http://stackoverflow.com/a/32201390/1677912
var i,j,total = 0, mean = 0, diffSqredArr = [];
for(i=0;i<array.length;i+=1){
total+=array[i];
}
mean = total/array.length;
for(j=0;j<array.length;j+=1){
diffSqredArr.push(Math.pow((array[j]-mean),2));
}
return (Math.sqrt(diffSqredArr.reduce(function(firstEl, nextEl){
return firstEl + nextEl;
})/array.length));
}