There is a new version out, but the documentation is somewhat lacking a working example.
Github Ticket: https://github.com/jbmusso/gremlin-javascript/issues/109
I've been trying to get an example to work. Any help appreciated:
gremlin-server: 3.3.2 with config gremlin-server-modern.yaml
npm gremlin lib: 3.3.2
import gremlin from 'gremlin';
import DriverRemoteConnection from 'gremlin/lib/driver/driver-remote-connection';
import { Graph } from 'gremlin/lib/structure/graph';
const graph = new Graph()
const g = graph.traversal().withRemote(new DriverRemoteConnection('ws://localhost:8182/gremlin', { mimeType: 'application/vnd.gremlin-v3.0+json' }));
const fetchById = async (id) => {
const result = await g.V(id).toList()
console.log(result);
}
const addUser = async (name) => {
const newVertex = await g.addV().property('name','marko').property('name','marko a. rodriguez').next()
console.log(newVertex)
}
addUser()
fetchById(0)
Current Output:
[]
{ value: null, done: true }
UPDATE
Gremlin JavaScript now supports GraphSON3 and the latest Gremlin Server.
Working example:
const gremlin = require('gremlin');
const Graph = gremlin.structure.Graph;
const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection;
Obtain a traversal source (g):
const graph = new Graph();
const connection = new DriverRemoteConnection('ws://localhost:8182/gremlin');
const g = graph.traversal().withRemote(connection);
Once you have a traversal source (g), reuse it across your application to create traversals, for example:
// Get the friends' names
const friends = await g.V().has("name","Matt")
.out("knows").values("name").toList();
See more information on the documentation: https://tinkerpop.apache.org/docs/current/reference/#gremlin-javascript
ORIGINAL ANSWER
Gremlin JavaScript doesn't support GraphSON3 serialization, which is the default in TinkerPop 3.3+. This causes your response to not be properly parsed.
I've filed a ticket to support GraphSON3 in the JavaScript GLV: https://issues.apache.org/jira/browse/TINKERPOP-1943
In the meantime, as a workaround, you can add GraphSON2 serializers to the server by adding the following line to your yaml, below serializers:
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV2d0, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV2d0] }}
Regarding the read property 'reader' of undefined issue. I falled back to version gremlin#3.3.4 and it works fine.
Related
I have the following config set in tracing.js (1:1 from the documentation) and I can't figure out how to set the service name. Right now in Datadog all I see is "unknown_service".
const opentelemetry = require("#opentelemetry/sdk-node");
const { getNodeAutoInstrumentations } = require("#opentelemetry/auto-instrumentations-node");
const { OTLPTraceExporter } = require("#opentelemetry/exporter-trace-otlp-http");
const { diag, DiagConsoleLogger, DiagLogLevel } = require('#opentelemetry/api');
//How can I set custom service name?
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);
const sdk = new opentelemetry.NodeSDK({
traceExporter: new OTLPTraceExporter({
url: process.env.OPENTELEMETRY_URL,
headers: {},
}),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
There are a couple of ways to do that:
First adding it to your code:
const opentelemetry = require("#opentelemetry/sdk-node");
const { getNodeAutoInstrumentations } = require("#opentelemetry/auto-instrumentations-node");
const { OTLPTraceExporter } = require("#opentelemetry/exporter-trace-otlp-http");
const { Resource } = require('#opentelemetry/resources');
const { SemanticResourceAttributes } = require('#opentelemetry/semantic-conventions');
const { diag, DiagConsoleLogger, DiagLogLevel } = require('#opentelemetry/api');
//How can I set custom service name?
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);
const sdk = new opentelemetry.NodeSDK({
traceExporter: new OTLPTraceExporter({
url: process.env.OPENTELEMETRY_URL,
headers: {},
}),
instrumentations: [getNodeAutoInstrumentations()],
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: '<service-name>',
}),
});
sdk.start();
Another way is using the environment variable OTEL_SERVICE_NAME as recommended by #Jan Garaj:
OTEL_SERVICE_NAME=<service-name>
At last, you can also use the environment variable OTEL_RESOURCE_ATTRIBUTES:
OTEL_RESOURCE_ATTRIBUTES=service.name=<service-name>
Those are the official OpenTelemetry ways of naming a service, IDK if they work with the backend you are using.
That works with OSS tools like Jager and Zipkin.
Try to set general-purpose environment variable OTEL_SERVICE_NAME.
Doc: https://opentelemetry.io/docs/concepts/sdk-configuration/general-sdk-configuration/
I have a container of cost guides in my Azure Cosmos DB (using the core SQL API). Each cost guide has an array of materials. I need to add a material to this array in every document in the container. Is this possible with javascript in a single transaction? I am familiar with partially updating documents individually using the patch operation but I would prefer to do it all at once if possible. I'm using the #azure/cosmos version 3.15 package
This is how I update individual documents in my function app:
const CosmosClient = require('#azure/cosmos').CosmosClient;
const config = require('../config/config');
const { endpoint, key, databaseId } = config;
const client = new CosmosClient({ endpoint, key });
const database = client.database(databaseId);
module.exports = async function (context, req) {
const containerId = req.query.containerId;
const container = database.container(containerId);
const id = req.query.id;
const updates = req.body;
const querySpec = {
query: `SELECT * from c where c.id = "${id}"`
}
const { resources: items } = await container.items
.query(querySpec)
.fetchAll()
const patchOp = [];
// loop through updates object
Object.keys(updates).map(key => {
patchOp.push({
op: 'replace',
path: `/${key}`,
value: updates[key]
})
})
const { resource: patchSource } = await container.item(items[0].id, items[0].id).patch(patchOp);
}
Technically, till now no such type of single transaction using Java Script is available. There are other possibilities like using .NET which are used for similar requirements.
Other languages like JAVA and PYTHON are having partial implementation. Terraform can also help a bit in partial implementation.
https://learn.microsoft.com/en-us/azure/cosmos-db/sql/sql-api-sdk-bulk-executor-dot-net
The closest I have seen is using the bulk or batch operation on items within a container. For example:
const operations = [
{
operationType: "Create",
resourceBody: { id: "doc1", name: "sample", key: "A" }
},
{
operationType: "Upsert",
partitionKey: 'A',
resourceBody: { id: "doc2", name: "other", key: "A" }
}
];
await database.container.items.batch(operations);
Link to azure documentation: https://learn.microsoft.com/en-us/javascript/api/#azure/cosmos/items?view=azure-node-latest##azure-cosmos-items-batch
I'm new to working with blockchain and I'm having a problem trying to get the contract from Uniswap. I've been following their docs on V3 but I can't get past this "abi.map is not a function" error. When I output the ABI to the console, it looks like I get the ABI back correctly but when I try to use it to initialize the contract I get this error.
import { ethers } from 'ethers'
const ABI = require('#uniswap/v3-core/artifacts/contracts/interfaces/IUniswapV3Pool.sol/IUniswapV3Pool.json')
console.log(ABI)
const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/Your Address Here;p')
const poolAddress = '0x8ad599c3A0ff1De082011EFDDc58f1908eb6e6D8'
const poolContract = new ethers.Contract(poolAddress, ABI, provider)
interface Immutables {
factory: string
token0: string
token1: string
fee: number
tickSpacing: number
maxLiquidityPerTick: number
}
async function getPoolImmutables() {
const [factory, token0, token1, fee, tickSpacing, maxLiquidityPerTick] = await Promise.all([
poolContract.factory(),
poolContract.token0(),
poolContract.token1(),
poolContract.fee(),
poolContract.tickSpacing(),
poolContract.maxLiquidityPerTick(),
])
const immutables: Immutables = {
factory,
token0,
token1,
fee,
tickSpacing,
maxLiquidityPerTick,
}
return immutables
}
getPoolImmutables().then((result) => {
console.log(result)
})
This error will go away if you delete everything in the abi up to the first square bracket after "abi". So for IUniswapV3Pool.json, instead of:
{
"_format": "hh-sol-artifact-1",
"contractName": "IUniswapV3Pool",
"sourceName": "contracts/interfaces/IUniswapV3Pool.sol",
"abi": [
{
"anonymous": false,
"inputs": [
...
It should be:
[
{
"anonymous": false,
"inputs": [
And don't forget to delete everything up to the last square bracket at the end of the file as well.
To build on #jaspers answer you don't actually need to delete anything from the original file. you just need to pass the abi property from the original.
const poolContract = new ethers.Contract(poolAddress, ABI.abi, provider)
I am using nodejs for the server.
Currently I have a Json in my project folder.
name.json
{
"name_English": "Apple",
"name_German": "Apfel",
"name_French": "Pomme"
}
When I send request to server, it returns:
GET http://localhost:3030/name
{
"name_English": "Apple",
"name_German": "Apfel",
"name_French": "Pomme"
}
But I found it is not convenient for frontend development.
Is there any way to do something like below?
GET http://localhost:3030/name?lang=en
{
"name": "Apple"
}
GET http://localhost:3030/name?lang=fr
{
"name": "Apfel"
}
Edit 1
The code of getting the Json in Feathers.js
name.class.js
const nameLists = require('../name.json')
exports.Test = class Test {
constructor (options) {
this.options = options || {};
}
async find (params) {
return nameLists
}
};
Edit 2
Is it possible to make name.json like this?
{
"name": ${name}
}
Edit 3
The reason I want to achieve above because I have to return whole Json file.
For the internationalization library, it seems needed to handle outside the JSON and I don't know what is the best practise to do so.
Here's a full demonstration with just express. (Hope that's ok.)
const express = require('express');
const app = express();
const port = 3030;
const nameLists = require('./name.json');
const unabbreviateLanguage = {
en: 'English',
de: 'German',
fr: 'French'
}
function filterByLanguage(obj, abbr) {
let language = unabbreviateLanguage[abbr];
let suffix = '_' + language;
let result = {};
for (let key in obj) {
if (key.endsWith(suffix)) {
let newkey = key.slice(0, -suffix.length);
result[newkey] = obj[key];
}
}
return result;
}
app.get('/name', (req, res) => {
res.json(filterByLanguage(nameLists, req.query.lang));
});
app.listen(port);
e.g.:
curl http://localhost:3030/name?lang=de
output:
{"name":"Apfel"}
The idea is to iterate over the keys of the input object and prepare an output object that only has keys that match the language suffix (then strip off that suffix). You'll likely want to either have a mapping of en -> English, or just use the key names that match the parameter e.g., rename name_English to name_en.
In FeathersJS, the params object of find will store the query string of the passed in URL. So if you call http://localhost:3030/name?lang=en, the params object will be :-
{
query: {
lang: 'en'
}
}
You can then use this information to determine which result from the JSON to return.
https://docs.feathersjs.com/guides/basics/services.html#service-methods
Your question appears to be two parts: handling queries, and handling the internationalization.
Handling the query:
Feathers presents queries through the context object at the following location:
context.params.query
Handling Internationalization:
There are many solid packages available for handling internationalization:
https://openbase.com/categories/js/best-nodejs-internationalization-libraries?orderBy=RECOMMENDED&
I have a React component which is pulling JSON data via an axios.get call and then I am mapping an embedded object using the following function:
axios.get('MasterData.json').then(response => {
const fullTree = response.data.graph.tree;
const resultTree = Object.keys(fullTree).map(key => ({
...fullTree[key],
id: key
}));
This produces the following:
{5bd356cc-5ee6-49a0-ab68-65cbf0209105: Array(6), id: "5bd356cc-5ee6-49a0- ab68-65cbf0209105"}
which is great, but I need to add a label of "ports: to the entire nested array (Array(6)) that is being output above so that I can map it. Any help is appreciated.
axios.get('MasterData.json').then(response => {
const fullTree = response.data.graph.tree;
console.log(fullTree) // you must check this fist
const resultTree = Object.keys(fullTree).map(key =>
new Port({ // create some function to generate get port as you want
port : fullTree[key],
id: key
)
});
for create function maybe on bellow me can explain more :)