I need some help to get js_of_ocaml working. There's not much information about it on the net, and the manual is very sparse (no snippets or usage examples, no comment sections).
I have a Card module on the server with a card record. I'm sending a card list to the client using Ajax, and there I want to read and traverse this list. What I end up with is this:
let json = Json.unsafe_input (Js.string http_frame.XmlHttpRequest.content) in
...where json has type 'a, according to documentation (not when I run it, of course).
I can log json##length and get the correct length of the list. Where do I go from here? Ideally, I'd like to use Deriving_Json to type-safe get a card list again, but I could also use a for-loop (not as elegant, but whatever).
Type declarations like type name = ... deriving(Json) creates Json_name module.
Here is example.
type card = {a: int; b: string; } deriving(Json)
type t = card list deriving(Json)
let _ =
let str = Json.to_string<t> [{a = 10; b = "abc";}; {a = 20; b = "xyz";}] in
let rs = Json.from_string<t> str in
Firebug.console##log(Js.string str);
List.iter (fun r -> Firebug.console##log_2(r.a, Js.string r.b)) rs
And I'm not sure why, I got "Uncaught ReferenceError: unix_inet_addr_of_string is not defined".
So add function unix_inet_addr_of_string () {return 0;} to js file.
Related
I just need to merge two files with the same list, but with different values on each file. Preferably in JavaScript
For example:
File 1
{"list1":{"a":1,"b":2}
{"list2":{"c":3,"d":4}
File 2
{"list1":{"a":5,"b":6}
{"list2":{"c":7,"d":8}
The desired result is
{"list1":{"a":6,"b":8}
{"list2":{"c":10,"d":12}
Sorry for the noob question, but the person who sent me the files should have done this themselves, but are currently unavailable. The files are too big to do by hand.
This is not very flexible code, but it would be far more work, to make something more dynamic. You would have to parse the objects recursevely and check if the property is an object and then jump deeper. Until ou find the values.
And please be aware that I'm not making any type checking whatsoever. If the data contains faulty data it is not cought properly. Also this code requires this exact structure. If your object contains other properties it might crash too.
// your data
const f1l1 = '{"list1":{"a":1,"b":2}}';
const f1l2 = '{"list2":{"c":3,"d":4}}';
const f2l1 = '{"list1":{"a":5,"b":6}}';
const f2l2 = '{"list2":{"c":7,"d":8}}';
var result1= JSON.parse(f1l1);
var result2= JSON.parse(f1l2);
//the names of the list as they appear in your real data *must* be the first object
const nameList1 = Object.keys(result1)[0];
const nameList2 = Object.keys(result2)[0];
//remove the list name
result1=result1[nameList1];
result2= result2[nameList2];
//get data from other file nd remove list name
const file2List1= JSON.parse(f2l1)[nameList1];
const file2List2= JSON.parse(f2l2)[nameList2];
// go through all items and sum them if the value is already in the list, else put it in for list1
for (var prop in file2List1) {
if (Object.prototype.hasOwnProperty.call(file2List1, prop)) {
if(Object.prototype.hasOwnProperty.call(result1, prop)){
result1[prop] = result1[prop] + file2List1[prop];
}else{
result1[prop] = file2List1[prop];
}
}
}
// and now for list2
for (var prop in file2List2) {
if (Object.prototype.hasOwnProperty.call(file2List2, prop)) {
if(Object.prototype.hasOwnProperty.call(result2, prop)){
result2[prop] = result2[prop] + file2List2[prop];
}else{
result2[prop] = file2List2[prop];
}
}
}
//put names of lists back in.
result1 = {[nameList1]:result1};
result2 = {[nameList2]:result2};
//check results:
console.log("input data:");
console.log(JSON.parse(f1l1));
console.log(JSON.parse(f1l2));
console.log(JSON.parse(f2l1));
console.log(JSON.parse(f2l2));
console.log("output data:");
console.log(result1);
console.log(result2);
You can try this out
newList = list1.concat(list2);
I'm currently trying to implement some basic Prolog queries in Tau-Prolog. Although I have working queries in SWI-Prolog, I can't implement them to work in Tau-Prolog.
I would like to return the name of all Robots that are in the database and have the Interface "B".
Is there something important I am missing here? I think that sub_string/5 might be the reason why it's not working. It also won't work when I paste the Code into the trial interpreter on http://tau-prolog.org/
Does anyone know a way to fix this query so it could work in Tau-Prolog? Thanks in advance!
<script>
var session = pl.create(1000)
var database = `
robot('Roboter1','A', 1, 550).
robot('Roboter2','C', 2, 340).
robot('Roboter3','B', 2, 430).
robot('Roboter4','A', 2, 200).
robot('Roboter5','B', 3, 260).
`
function start_query_RwB(){
query_RwB();
}
function query_RwB(){
var queryRwB = "queryRwB :-write('Interface B has: '),robot(Name, Interface,_,_),sub_string(Interface,_,_,_,'B'),write(Name),nl, fail."
var code_pl = database.concat(queryRwB);
var parsed = session.consult(code_pl)
var query = session.query('queryRwB.')
function inform(msg) {
show_result4.innerHTML += msg
}
session.current_output.stream.put = inform;
var callback = function(answer) {
}
session.answer(callback);
}
</script>
Use sub_atom/5 instead of sub_string/5 in the definition of the queryRwB variable as you use atoms, not strings, in the definition of the predicate robot/4:
var queryRwB = "queryRwB :-write('Interface B has: '),robot(Name, Interface,_,_), sub_atom(Interface,_,_,_,'B'),write(Name),nl, fail."
Note that sub_atom/5 is a standard predicate (that's implemented by Tau Prolog) while sub_string/5 is a proprietary predicate only found in some Prolog systems like ECLiPSe and SWI-Prolog.
I have this database, which looks like this
so the first keys are user uid taken from auth, and then the username he/she provided and what did they score for each match are taken also..
I just wanted to get each user total points - for example Ray total points is 45 and Wood total points is 44 but after looking through for the docs all I was able to do was just for one user, I have to write each user name and the specific match for each line to get the value.. now think of how it will be if they are dozens of users? hmm a lot of lines..
here is the JSON
the javascript code
var query = firebase.database().ref();
query.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key;
var Data1 = childSnapshot.child("Ray/Match1/Points").val();
var Data2 = childSnapshot.child("Ray/Match2/Points").val();
console.log(Data1 + Data2);
});
})
which will let me display, Ray total points, but not for Wood obviously I have to repeat it and write it..
So how do i solve this?
I took a look at your problem and I think I have your solution, or at the very least a PATHWAY to your solution. Ok, first I'll explain the basic issue, then I'll attempt to provide you with some generic-ish code (I'll attempt to use some of the variables you used). And away we go!
Basically what I see is 2 steps...
STEP 1 - You need to use a "constructor function" that will create new user objects with their own name (and/or user ID) and their own set of properties.
With that line of thinking, you can have the constructor function include properties such as "user name", "match points 1", "match points 2" and then a function that console logs the summary of each name and their total points from match points 1 and 2.
STEP 2 - You need to put the constructor function inside of a loop that will go through the database looking for the specific properties you need to fill in the properties needed by the constructor function to spit out the info you're looking for.
So... and let's take a deep breath because that was a lot of words... let's try to code that. I'll use generic properties in a way that I think will make it easy for you to insert your own property/variable names.
var user = function(name, match1, match2){
this.name = name;
this.match1 = match1;
this.match2 = match2;
this.pointTotal = function(match1, match2) {
console.log(match1 + match2);};
this.summary = function(){
console.log(name + " has a total of " + pointTotal + "
points.");};
}
the "This" part of the code allows ANY user name to be used and not just specific ones.
Ok, so the code above takes care of the constructor function part of the issue. Now it doesn't matter how many users you need to create with unique names.
The next step is to create some kind of loop function that will go through the database and fill in the properties needed to create each user so that you can get the total points from EVERY user and not just one.
Again, I will use generic-ish property/variable names...
var key = childSnapshot.key;
while(i = 0; i < key.length + 1; i++) {
var user = function(name, match1, match2){
this.name = name;
this.match1 = match1;
this.match2 = match2;
this.pointTotal = function(match1, match2) {
console.log(match1 + match2);};
this.summary = function(){
console.log(name + " has a total of " + pointTotal + " points.");};
}
}
That is a whole lot of words and the code is a hybrid of generic property names/variables and of property names/variables used by you, but I'm certain that I am on the correct pathway.
I have a lot of confidence that if you used the code and EXPLANATION that I provided, that if you plug in your own variables you will get the solution that you need.
In closing I just want to say that I REALLY hope that helps and if it doesn't I'd like to help solve the problem one way or another because I need the practice. I work a job with weird hours and so if I don't answer right away I am likely at my job :(
Good luck and I hope I helped!
simply add total node to your db
|_Id
|_ $userId:
| |_ Ray
| | |_ Match1:24
| | |_ Match2:21
| |_ total:45
and then get user`s total
var query = firebase.database().ref();
query.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var total = childSnapshot.child("total").val();
console.log(total);
});
})
you can add the total node using cloud functions
Check out this implementation. No need for cloud function.
firebase().database().ref().on('value', function(snapshot) {
snapshot.forEach((user)=>{
user.forEach((matches)=> {
var total = 0;
matches.forEach((match)=> {
total += match.val().Points;
});
console.log(total);
});
});
})
If the key is the user's Id, why add yet another nested object with the user's name? Do you expect one user to have multiple usernames? That sounds weird and adds on complexity, as you have probably noticed. If you need to keep the user name somewhere in Firebase, it is recommended that you dedicate a user details section somewhere directly under the user Id key. Here is a JavaScript representation of the Firebase object structure:
{
a1230scfkls1240: {
userinfo: {
username: 'Joe'
},
matches: {
asflk12405: {
points: 123
},
isdf534853: {
points: 345
}
}
}
}
Now, getting to the total points seems a bit more straightforward, does it not? 😎
To help you without modifying your current database structure, all you need is to loop through all the userId+username+matches permutation in your database. Here is an example code to achieve just that, you do not need any special Firebase feature, just good old JavaScript for-of loop:
const query = firebase.database().ref();
query.once('value')
.then(snapshot => {
const points = {}
const users = snapshot.val()
for (const userId of Object.keys(users)) {
const userprofile = users[userId]
for (const username of Object.keys(userprofile)) {
const user = userprofile[username]
for (const matchId of Object.keys(user)) {
const match = user[matchId]
// Store the points per user, per profile, or per both, depending on your needs
points[username] = points[username] === undefined
? points[username] = match.points
: points[username] += match.points
}
}
}
})
I have developed a pretty basic audio player on on my website similar to SoundClouds.
I have managed to successfully finish it, and I am starting to clean up all the markup, including (trying) removing all inline event handlers (i.e: onclick="" or onkeyup="").
However, I have come across a bit of a problem in my JavaScript whilst doing this.
It's a bit hard to explain so I'm going to post my JavaScript, then give you an idea of what the problem is:
$(".track-w__trigger").click(function(){
var tid = $(this).attr('aria-trackid'); // aria-trackid is equal to a random integer created by PHP
var tiW = 'w' + tid + 'w'; // this is an object (i.e: w3w)
playPauseButton(this, tiW, ti);
});
function playPauseButton(button, wave, trackID){
var button = $(button);
if(wave.isPlaying()){ // the object (w3w.isPlaying())
button.removeClass("playing");
wave.pause();
} else {
button.addClass("playing");
wave.play();
}
}
What I used to have was
<div class="track-w__trigger" onclick="playPauseButton(this, w3w, 3)" id="w3w-trigger"></div>
and now it is:
<div class="track-w__trigger" aria-trackid="3" id="w3w-trigger"></div>
As you can see in the second block of code. w3w is an object. However, because I have set it using my click function in a separate script using string quotes. JavaScript has gone ahead and made it a string.
So now when I use wave.isPlaying() for example; it does nothing.
I have no idea how to fix this, and no result on Google will help me. Any help in fixing this issue would be greatly appreciated,
Thanks!
EDIT:
This is where & how w3w is set:
var w3w = Uki.start({
// e.t.c
});
Use eval
wave = eval(wave);
to evaluate the string as a function
or use a safer way
wave = window[wave];
https://jsfiddle.net/zmr412q7/
Instead of having each object as a seperate variable, create an object that contains each object at the id representing the N in wNw. Ex:
var wNw = {};
// represents w1w
wNw[1] = (Uki.start({
// e.t.c
}));
// represents w17w
wNw[17] = (Uki.start({
// e.t.c
}));
// represents w3w
wNw[3] = (Uki.start({
// e.t.c
}));
This gives you an object that looks like:
{
1: object_that_was_w1w
17: object_that_was_w17w
3: object_that_was_w13w
}
And then your click handler looks like this:
$(".track-w__trigger").click(function(){
var tid = $(this).attr('aria-trackid'); // aria-trackid is equal to an integer of 1 to 5
var tidNum = parseInt(tid);
playPauseButton(this, wNw[tidNum], ti);
});
You can try something like this,
var tid='w'+5+'w';
var tryout=tid.valueOf();
console.log("getting the object "+tryout)
The valueOf property converts the string to an object
Hi there before I start I did try looking through the search about writing variables so if this has been asked and answered then I do apologise but this is baffling me ....
So here goes ..
example of what I am talking about
var i = e[ab]
var n = e[cd][ef]
var t = e[cd][gh]
I know that when I want var i I can put e.ab but how would I go about writing var n and var t
So assuming your object looks like this (based on your description, it sounds like you want to access an object which is the property of another object), and you want to access them through the indexer properties (which would be a property of a property).
var e = {
ab : "variableOne",
cd : {ef:"ef object"},
gh : {ij:"ij object"},
}
var i = e["ab"]
//if these are properties, then you need to add quotes around them
//to access a property through the indexer, you need a string.
var n = e["cd"]["ef"]
var t = e["gh"]["ij"]
console.log(i);
console.log(n);
console.log(t);
console.log("this does the same thing:")
console.log(e.ab);
console.log(e.cd.ef);
console.log(e.gh.if);
In your example the object would look like
//e is the parameter, but I show it as a variable to show
// it's relation to the object in this example.
e = {
now_playing: {artist:"Bob Seger"; track:"Turn the Page"}}
}
this is different than an array of arrays:
var arr = [
['foo','charlie'],
['yip', 'steve'],
['what', 'bob', 'jane'],
];
console.log(arr[0][0]); //foo
console.log(arr[0][1]); //charlie
console.log(arr[1][0]); //yip
console.log(arr[1][1]); //steve
console.log(arr[2][2]); //jane
https://jsfiddle.net/joo9wfxt/2/
EDIT:
Based on the JSON provided, it looks like parameter e in the function is assigned the value of the item in the array. With your code:
this line will display: "Rock you like a hurricane - Nontas Tzivenis"
$(".song_title .current_show span").html(e.title);
and this line will display: "Rascal Flatts - Life is a Highway".
$(".song_title .current_song span").html(e.np);
If it's not displaying you might want to double check your JQuery selectors. This ".song_title .current_song span" is selecting it by the classes on the element.
I think you are in need of a bit of a refresher on basic JavaScript syntax. Here's how you can assign an "empty object" to a variable, then start to assign values to it's properties:
e = {}
e.ab = {}
e.cd = {}
e.cd.ef = "data"
or you can use the associative array syntax for property access:
e = {}
e["ab"] = {}
e["cd"] = {}
e["cd"]["ef"] = "data"
You see the latter is using the object e like a two-deep associative array. Is that what you are looking to do?
JavaScript is not strongly typed. So an Array "a" could contain objects of different types inside.
var a = [ "a value", [1, 2, 3], function(){ return 5 + 2;}];
var result = a[0]; //get the first item in my array: "a value"
var resultOfIndexedProperty = a[1][0]; //Get the first item of the second item: 1
var resultOfFunc = a[2](); //store the result of the function that is the third item of my array: 7
Hope this helps a little.