Neo4jClient with keylines - javascript

Introduction:
I am a newbie to Neo4jClient so forgive me if i ask something that has been asked before. But i have been stuck on this forever.
What i Am trying to do:
I am trying to connect Neo4j with Keylines using .NET.
Cause:
First, i used Neo4j's REST with Jquery AJAX to do Return (*) which returned everything including data and URI's of self, start, end, all_Relationships etc.
data: Object
end: "http://localhost:7474/db/data/node/93"
extensions: Object
metadata: Object
properties: "http://localhost:7474/db/data/relationship/4019/properties"
property: "http://localhost:7474/db/data/relationship/4019/properties/{key}"
self: "http://localhost:7474/db/data/relationship/4019"
start: "http://localhost:7474/db/data/node/6"
type: "SENT"
Hence i was able to use self as a ID for keylines Node and start and end URI's as Keyline's Link id1 and id2.
function queryNeo4j(query) {
var request = $.ajax({
type: "POST",
url: "http://localhost:7474/db/data/cypher",
contentType: "application/json",
data: JSON.stringify({ "query": query, "params": {} }),
success: afterQueryNeo4j
});
};
function afterQueryNeo4j(json) {
console.log(json); // returned data from ajax call
makeNodes(json);
makeLinks(json);
//console.log(items);
createKeylines(items);
};
// populates global var itmes with nodes
function makeNodes(param) {
for (i = 0; i < param.data.length ; i++) {
for (j = 0 ; j < 2 ; j++) {
var node = {
type: 'node',
id: param.data[i][j].self,
dt: stringToDateConverter(String(param.data[i][1].data.yyyyMMdd)),
b: 'rgb(100,255,0)',
c: 'rgb(0,0,255)',
t: param.data[i][j].data.name,
subject: param.data[i][j].data.subject
};
items.push(node);
}
}
};
// populates global var itmes with nodes
function makeLinks(json) {
for (i = 0; i < json.data.length; i++) {
var link = {
type: 'link',
id: json.data[i][2].self,
id1: json.data[i][2].start,
id2: json.data[i][2].end,
t: json.data[i][2].metadata.type,
w: 2,
c: 'rgb(0,0,255)'
}
items.push(link);
}
}
Using this technique i was successfully able to plot keylines graph and timebar using only client side Javascript.
but problem Arose when i published this on IIS, it gave me Cross-Domain error which means i had to call Neo4j from server code (C#) and feed it to client side HTML/JS. That's when i found out about Neo4jClient.
Done so Far:
I am Successfully able to read data from Neo4j in my C# code using
public class Person
{
public string name { get; set; }
public int dob { get; set; }
}
var query = client.cypher
.match(("person:Person"))
.return(person => person.As<Person>());
var result = query.results;
foreach (var i in result)
{
Console.WriteLine("people name is:"+i.name);
}
Problem:
Now, i can read only data based on my Cypher Query but can't read other stuff like id, self, start, end URI's and relationships which i need for my UI.
Is there a way to get the Return (*) and all the other meta data using neo4jclient? Any code will help.
Should i stick to Client side ajax call by resolving cross reference errors using JSONP or CORS since it was much easier but i am afraid that it might give me some problems down the line as it is not the proper way to do it?
I can't seem to find any proper documentation for Neo4jClient.
There are so many options i see for return in Intellisense but dont't know how i can use them.
Any help is greatly appreciated.
Thanks in advance.

You can change your return to be:
.Return(person => person.As<Node<Person>>());
Which will return a wrapper around the Data containing all the node goodness, that should get you there.

Related

ASP.NET WebApi POST not recognizing form-urlencoded int array

So this post gives an answer to how to send a post for downloading a file using forms. But my API endpoint isn't recognizing the form data.
[HttpPost]
public async Task<IHttpActionResult> DownloadPdfs([FromBody] IEnumerable<int> ids)
{
if (ids == null || ids.Count() < 1)
{
return BadRequest("No ids supplied.");
}
...
'ids' always has a count of 0.
Here's the JS code:
function downloadFile(ids) {
var win = 'w' + Math.floor(Math.random() * 1000000000000);
window.open('', win, 'width=250, height=100');
var f = $('<form></form>')
.attr({ target: win, method: 'post', action: 'api/pdfs' })
.appendTo(document.body);
_.each(ids, function (id) {
$('<input></input>')
.attr({ type: 'hidden', name: 'ids', value: id })
.appendTo(f);
});
f[0].submit();
f.remove();
}
Initially, I just had it the same as the other linked answer which was just one input appended to the form, in which I set the value to 'ids'. I tried this next, but that still didn't work.
Does anyone know how to adapt this to still use post data to provide my ids, which are needed to create and supply the downloaded file? Or is there a better way to do this?
I've tried doing it just using Ajax, which returns the file content in the responseText, but I can't make use of it in there and I can't get the browser to open it.
Edit 1
I also just tried setting the value to this:
value: '{ids: [' + ids.toString() + ']}'
That didn't work.
Edit 2
Just tried changing the endpoint parameter to this:
([FromBody] int[] ids)
...to no avail.

How to return data with date range with Laravel 5.2?

So what I am trying to do is produce a trial balance report. I have to get all chart of accounts(coas) and sum of its debit and sum of its credit between two dates. I have these tables in the database and these are their attributes
Client: id, name
Coas: id, name
Journal: id, description, date
Journal_details: id, journal_id, coa_id, debit, credit
I have already put their relationships in the model.
Client.php
public function coas()
{
return $this->belongsToMany('App\Coa');
}
public function journal(){
return $this->hasMany('App\Journal');
}
Coa.php
public function clients(){
return $this->belongsToMany('App\Client');
}
public function journals_details(){
return $this->hasMany('App\JournalDetails');
}
Journal.php
public function journal_details(){
return $this->hasMany('App\JournalDetails');
}
public function client(){
return $this->belongsTo('App\Client');
}
JournalDetails.php
public function journal(){
return $this->belongsTo('App\Journal');
}
public function coa()
{
return $this->belongsTo('App\Coa');
}
I'm trying to get all of the coas with journal details of a specific client, which I am already doing.
$trials = $client->coas()->with('journals_details')->get();
However, I am using a date range to select only those that belonged to specific date that is inputted. Here is my controller. I tried this but it doesn't work.
public function trial_balance_generate(Request $request)
{
$client = Client::find($request->client_id);
$start = \Carbon\Carbon::parse($request->from)->startOfDay();
$end = \Carbon\Carbon::parse($request->to)->endOfDay();
$data= $client->coas()->with('journals_details')->whereBetween('date',[$start,$end])->get();
return response()->json($data);
}
I know there is something wrong with how I get the data. I just don't know how to get all the coas and its details with the journal header that contains the date.
This is my javascript for getting the date range.
$('.date').on('change', function() {
var from = $('#from').val();
var to = $('#to').val();
var client_id = $('.clientHidden').val();
$.ajax({
type : 'get',
url : '/user/'+client_id+'/reports/trialbalance/generate/',
dataType: 'json',
data : {
'from':from,
'to':to,
client_id':client_id
},
success:function(data){
$('td').remove();
for(var ctr = 0; ctr < data.length; ctr++)
{
$('#reportTbody').append()
'<tr><td>'+ data[ctr].name +'</td><td>{{$trial->journals_details->sum("debit")}}</td><td>{{$trial->journals_details->sum("credit")}}</td></tr>'+
}
}
});
});
Here is a photo of what I am trying to achieve https://imgur.com/a/IZvio That returns everything so no dates yet.
Is the date on your model a carbon instance? Otherwise they aren't comparable.
You can to set it as a Carbon instance on the model in the $date property:
protected $dates = [
'created_at',
'updated_at',
'date'
];
By doing this, you are overriding $datesso be sure to include created_atand updated_at (and deleted_atif you're using soft delete).
Documentation link
I think you need to debug the sql laravel executed and find out if it is as expected. The way to fetch executed sqls in laravel is use \DB::enableQueryLog():
In your controller method:
DB::enableQueryLog();
#your laravel query goes here
$laQuery = DB::getQueryLog();
#optionally disable the query log:
DB::disableQueryLog();
then you can print the sql executed before and check out if it is as expected!

Return list to JSON to Angularjs

It is such that I must have sent some content from my controller over to Angularjs which shall come forth with words such as only L in themselves or E, so it goes in other words, of words where it like just let the words sign which has the single letter.
There is no fault forward by the console and what I believe is the problem is that it does not specify any value to the side.
i have try its here:
A circular reference was detected while serializing an object of type 'SubSonic.Schema .DatabaseColumn'.
Load.js
var app = angular.module('WordSpreads',[]);
app.controller('WordSpreadsListValue', function ($scope, $http) {
$http(
{
method: 'GET',
url: '../Profile/MWordSpreads'
}).success(function (response) {
$scope.entries = data.List;;
});
console.log("TEST");//It does not appear in the console log.
});
Controller:
[HttpGet]
public JsonResult MWordSpreads()
{
WordsSpreadsListValue model = new WordsSpreadsListValue();
var db = HelperToTables.DbValue;
model.List = db.WordSpreads.ToList();
return Json(model.List, JsonRequestBehavior.AllowGet);
}
Model:
public class WordsSpreadsListValue
{
public List<WordSpread> List { get; set; }
}
Error giv me:
A circular reference was detected while serializing an object of type
'xxSitename.Models.LinqDatabase.WordSpread'
UPDATE:
model.List = db.WordSpreads.Select(x => new {
Name = x.name,
TextValue = x.text.ToString()
}).ToList();
ERROR :
Cannot implicitly convert type
'System.Collections.Generic.List<>' to
'System.Collections.Generic.List' MVCOrdklar2015
.
model.List = db.WordSpreads.Select(x => new { Prop1 = x.1, Prop2 = x.2}).ToList();
You are having trouble serializing model.List, the Json serialize is barfing on serializing model.List. If you make it a new object without navigation properties you will be fine.
In my experience it has to do with the navigation properties, I dont fully understand what it is. But, once you remove the navigation properties from the equation it will work.

ProtoBuf.js how to filter extra fields when encoding an object

I'm using Protobuf.js to write a hook for sails.js to be able to send message encoded by protocol buffers by socket.io.
Say I have a proto scheme Message.proto:
message Message{
required string message = 1;
optional string user = 2;
optional int32 id = 3;
}
And I'm getting an object from database as data:
data = {
message: 'Hello',
user: 'johnDoe',
id: 90,
createdAt: '2015-10-16T10:15:39.837Z',
updatedAt: '2015-10-16T10:15:39.837Z'
};
And I have a sails hook with code:
var ProtoBuf = require("protobufjs"),
Reflect = ProtoBuf.Reflect,
builder = ProtoBuf.newBuilder(),
protoModels;
...
// This method overrides socket.io broadcast call for sails.js models pubSub:
augmentModels: function () {
for (var identity in app.models) {
var protobufSchemeName = app.models[identity].protobufSchemeName;
// protobufSchemeName is the file name of the sheme
if (protobufSchemeName) {
ProtoBuf.loadProtoFile(path.join(app.config.appPath, app.config.protobuf.folder, protobufSchemeName + ".proto"), builder);
app.models[identity].broadcast = function (roomName, eventName, data, socketToOmit) {
var dataToSend = protoModels[protobufSchemeName].encode(???HERE???); //HERE I SHOULD PUT THE MODIFIED DATA WITH THE ONLY NECESSARY FIELDS
app.sockets.broadcast(roomName, eventName, dataToSend.toBuffer(), socketToOmit);
};
}
protoModels = builder.build();
}
}
I can't pass data directly this way: protoModels[protobufSchemeName].encode(data) because it will cause an error: this+"#"+keyOrObj+" is not a field, because data contains extra fields;
So here goes the question: what is the easiest and correct way to save to dataToSend only fields that are in the scheme (Message.proto)?
P.S. I know that should have something with Reflection and they say you can do it like this way:
var TPlayer = builder.lookup("Game.Player"); // instance of ProtoBuf.Reflect.Message
var fields = TPlayer.getChildren(ProtoBuf.Reflect.Message.Field); // instances of ProtoBuf.Reflect.Message.Field
fields.forEach(function(field) {
//Filter it here
});
But I can't figure it out how to to reach lookup method from protoModels. And maybe there is the way to use Builder's isMessageField method to filter fields in data?
We still have a builder there so the solution is quite the same as in example:
...
augmentModels: function () {
for (var identity in app.models) {
var protobufSchemeName = app.models[identity].protobufSchemeName;
if (protobufSchemeName) {
ProtoBuf.loadProtoFile(path.join(app.config.appPath, app.config.protobuf.folder, protobufSchemeName + ".proto"), builder);
app.models[identity].broadcast = function (roomName, eventName, data, socketToOmit) {
var fields = builder.lookup(protobufSchemeName).getChildren(ProtoBuf.Reflect.Message.Field).map(function (f) {
return f.name;
}); //Here are the fieldnames of the scheme as an array
var dataToSend = protoModels[protobufSchemeName].encode(_.pick(data, fields)).toBuffer();
app.sockets.broadcast(roomName, eventName, dataToSend, socketToOmit);
};
}
protoModels = builder.build();
}
}
Another way is to override emit/broadcast methods like I did in the hook below:
P.S. If anyone will find this useful:
I've made a Protobuf Serialization Hook for Sails.js. Contributions are welcome!

Kendo UI datasource sync() will not work

In the code below, the fetch() and sync() methods are not doing anything.
I am trying to see how the data in my localStorage gets updated and the methods are not updating it (example LS string is in the code)
Where am I going wrong?
function makeWorkingLS(collDesc, projDesc, Id, Description, ElapsedSeconds, ElapsedTime, WorkItemType){
//Create observable object from params
var activeTaskObject = kendo.observable ({
client: collDesc,
project: projDesc,
taskId: Id,
description: Description,
elapsedSeconds: ElapsedSeconds,
elapsedTime: ElapsedTime,
comment: WorkItemType
});
// example string in localStorage:
//{"client":"Morken Mindy","project":"Shazbat creation engine","taskId":183,"description":"Create the Shazbat 100% efficiency engine","elapsedSeconds":296803,"elapsedTime":"82h43m","comment":"Task"}
// Convert to JSON string for localStorage
var activeTask = JSON.stringify(activeTaskObject);
console.info(activeTask);
//Write to localStorage
window.localStorage.setItem("activeTask",activeTask);
//Set it as the active datasource for updating to webservice
var activeTaskDS = new kendo.data.DataSource({
transport: {
read: function(options){
taskItem = JSON.parse(localStorage["activeTask"]);
},
update: {
url: remUpd, //url var declared earlier in the process
dataType: "json"
}
},
schema: {
model: {
client: "client",
taskId: "taskId"
},
data: function(){
return taskItem;
}
}
});
activeTaskDS.fetch(function(){
activeTaskDS.data()[0].set("client", "NOBODY");
activeTaskDS.sync();
cosole.log("activeTaskDS.data()[0] : "+activeTaskDS.data()[0]); //should read 'NOBODY' but reads 'Morken Mindy'
});
}
Thanks in advance,
Neil.
I'm not sure what is the problem actually, but I have to point some important things:
AFAIK, when you customize any transport methods you have to pass the data into a callback in the options object:
transport: {
read: function(options){
taskItem = JSON.parse(localStorage["activeTask"]);
// Tells the widget to handle that collection
options.success(taskItem);
}
}
In schema.data it seems that you want to pass your data through this method(correct me if I'm wrong). But this method isn't for that purpose. It is used just to tell the widget which field to read(in case of passing a string to it) or to read a property from a response, which comes as a parameter that you are not using. Check the second example here. So this may not be right way to read the taskItem object as data;
Speaking about the taskItem object, it seems that its the base data of your dataSource but it isn't defined(at least on the snippet you posted). What I mean is, if you follow the step 1 you won't even need to read from that object no more.
Please let me know if this is helpful and if you need anyting more.

Categories