Deleting JSON object based on attribute - javascript

I am working with React, I have got a variable named newtreeData, which looks like:
var newTreeData = {
name: submitted_title,
resource_link: submitted_resource_link,
details: submitted_details,
uuid: submitted_uuid,
website_image: submitted_website_img,
children: [
{
name: "Edit and save",
resource_link: "uh",
uuid: uuid.v4(),
details: "hi",
website_image:
"https://cdn3.iconfinder.com/data/icons/harmonicons-06/64/plus-circle-512.png",
children: [{...}, {}, ...]
},
{
name: "Edit and save",
resource_link: "uh",
uuid: uuid.v4(),
details: "hi",
website_image:
"https://cdn3.iconfinder.com/data/icons/harmonicons-06/64/plus-circle-512.png"
}
]
};
The line children: [{...}, {}] is just representing that newTreeData's children can have children which can have children...
Anyways, I wrote a method name findUUIDthenDelete which should do in pseudocode: if(object.uuid == toFindUUID) then delete object, and here's the full code for findUUIDthenDelete:
findUUIDthenDelete = (orig_data, to_delete_uuid) => {
var targetIsFound = false;
if (orig_data.uuid == to_delete_uuid) {
targetIsFound = true;
}
if (targetIsFound == false) {
if (orig_data.children === undefined) {
} else {
//if target not found, run recursion
orig_data.children.map(eachChildren =>
this.findUUIDthenDelete(eachChildren, to_delete_uuid)
);
}
} else {
console.log(orig_data, "this is the child ");
console.log(orig_data.parent, "is found, deleting its parent");
delete orig_data
}
};
As you can see this method is two parts: first I locate the object which has the uuid that we are trying to seek (potentially with some recursions), then delete the object. However, right now I am getting the "delete in local variable strict mode blah blah" error because of doing delete orig_data. Any insights to any workarounds to that error or some totally new way of tackling this? Also sincere apologies if there is an obvious solution I am out of mental energy and unable to think of anything algorithmic at the moment.

This should do it:
function findUUIDthenDelete(tree, uuid) {
if (!tree.children) return;
tree.children = tree.children.filter(c => c.uuid !== uuid);
tree.children.forEach(c => findUUIDthenDelete(c, uuid));
}
Should be pretty self-explanatory.
First, if the current node has no children, exit right away.
Next, potentially remove a child from the children array if the uuid matches using filter().
Finally, recursion.

Ok I'll admit this turned out to be more complicated than I thought, but the solution below will work if you can use Immutable. Essentially it walks your objects and collects the path to find the object that has the uuid and then once it has done that, it removes it.
const testMap = Immutable.fromJS({
uuid: 1,
children: [{
uuid: 2,
children: [{
uuid: 3,
children:[{
uuid: 8
}]
},
{
uuid: 4
},
{
uuid: 5
},
]
},
{
uuid: 7
}]
});
function findPath(checkMap, uuid, pathMap, currentIndex) {
if (checkMap.has('uuid') && checkMap.get('uuid') === uuid) {
const updatePathMap = pathMap.get('path').push(currentIndex);
return new Immutable.Map({
found: true,
path: pathMap.get('path').push(currentIndex)
});
} else {
if (checkMap.has('children') && checkMap.get('children').size > 0) {
for (let i = 0; i < checkMap.get('children').size; i++) {
const child = checkMap.get('children').get(i);
const checkChildPath = findPath(child, uuid, pathMap, i);
if (checkChildPath.get('found') === true) {
let updatePath = checkChildPath.get('path').push('children');
updatePath = updatePath.push(currentIndex);
return new Immutable.Map({
found: true,
path: updatePath
});
}
}
}
return pathMap;
}
}
const testPath = findPath(testMap, 7, new Immutable.Map({
found: false,
path: new Immutable.List()
}), 0);
console.info(testPath);
const testPath2 = findPath(testMap, 8, new Immutable.Map({
found: false,
path: new Immutable.List()
}), 0);
console.info(testPath2);
if (testPath2.get('found') === true) {
const path = testPath2.get('path');
if (path.size === 1 && path.get(0) === 0) {
// Your highlest level map has the uuid
} else {
const truePath = path.shift();
const cleanedUpMap = testMap.removeIn(truePath);
console.info(cleanedUpMap);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.2/immutable.js"></script>

Related

Convert file path into object

Say I have the following strings:
"files/photos/foo.png"
"files/videos/movie.mov"
and I want to convert them to the following object:
{
name: "files"
children: [{
name: "photos",
children: [{
name: "foo.png",
id: "files/photos/foo.png"
}]
},{
name: "videos",
children: [{
name: "movie.mov",
id: "files/videos/movie.mov"
}]
}]
}
What would be the best approach for doing so? I've tried writing some recursive functions, however admit that I'm struggling at the moment.
Here's a quick snippet with a possible solution. It uses nested loops, the outer splitting each path by the delimeter and pop()ing the file portion out of the array. The inner iterates the parts of the path and constructs the heirarchy by reasigning branch on each iteration. Finally the file portion of the path is added to the deepest branch.
const data = [
'files/photos/foo.png',
'files/photos/bar.png',
'files/videos/movie.mov',
'docs/photos/sd.jpg'
];
const tree = { root: {} }
for (const path of data) {
const parts = path.split('/');
const file = parts.pop();
let branch = tree, partPath = '';
for (const part of parts) {
partPath += `${part}/`;
if (partPath === `${part}/`) {
tree.root[partPath] = (tree[partPath] ??= { name: part, children: [] });
} else if (tree[partPath] === undefined) {
tree[partPath] = { name: part, children: [] };
branch.children.push(tree[partPath]);
}
branch = tree[partPath];
}
branch.children.push({ name: file, id: path });
}
const result = Object.values(tree.root)
console.log(JSON.stringify(result, null, 2))
.as-console-wrapper { max-height: 100% !important; top: 0; }
.as-console-row::after { display: none !important; }
Or as a function.
function mergeAssets(assets) {
const tree = { root: {} }
for (const path of data) {
const parts = path.split('/');
const file = parts.pop();
let branch = tree, partPath = '';
for (const part of parts) {
partPath += `${part}/`;
if (partPath === `${part}/`) {
tree.root[partPath] = (tree[partPath] ??= { name: part, children: [] });
} else if (tree[partPath] === undefined) {
tree[partPath] = { name: part, children: [] };
branch.children.push(tree[partPath]);
}
branch = tree[partPath];
}
branch.children.push({ name: file, id: path });
}
return {
name: "assets",
children: Object.values(tree.root)
}
}
const data = [
'files/photos/foo.png',
'files/photos/bar.png',
'files/videos/movie.mov',
'docs/photos/sd.jpg'
];
const result = mergeAssets(data);
console.log(JSON.stringify(result, null, 2))
I was able to find a solution using a recursive function. If others have any tips on how to improve this, I'd love to hear.
function mergeObjects(parentArray,path,originalName){
if(originalName === undefined){
originalName = path;
}
const parts = path.split("/");
var nextPart = "";
parts.forEach((part, index) => index > 0 ? nextPart += (nextPart !== "" ? "/" : "") + part : null);
//does the parentArray contain a child with our name?
const indexOfChild = parentArray.findIndex(child => child.name === parts[0]);
if(indexOfChild === -1){
//this item does not exist
if(parts.length > 1){
var index = parentArray.push({
name: parts[0],
children : []
}) - 1;
mergeObjects(parentArray[index].children,nextPart,originalName);
}else{
parentArray.push({
name: parts[0],
id : originalName
});
}
}else{
//this item already exists
if(parts.length > 1){
mergeObjects(parentArray[indexOfChild].children,nextPart,originalName);
}
}
}
And the function is called with the following:
function mergeAssets(assets){
var obj = {
name: "assets",
children: []
};
assets.forEach(asset => mergeObjects(obj.children,asset));
return obj;
}

Check if userid matches one in the array

I'm attempting to check if a user's ID is in this array and if they are, also get the "text" from it.
Array:
const staff = [
{
user: '245569534218469376',
text: 'dev'
},
{
user: '294597887919128576',
text: 'loner'
}
];
I've tried if (staff.user.includes(msg.member.id)) (Which I didn't think was going to work, and didn't.)
const findUser = (users, id) => users.find(user => user.id === id)
const usersExample = [
{
id: '123456765',
text: 'sdfsdfsdsd'
},
{
id: '654345676',
text: 'fdgdgdg'
}
]
//////////////////
const user = findUser(usersExample, '123456765')
console.log(user && user.text)
The some method on an array is used to tell if an item meets a condition, it is similar to the find method but the find method returns the item where the some method return true or false.
const staff = [
{
user: '245569534218469376',
text: 'dev'
},
{
user: '294597887919128576',
text: 'loner'
}
];
const isStaff = (staff, id) => staff.some(s => s.user === id);
console.log(isStaff(staff, '123'));
console.log(isStaff(staff, '245569534218469376'));
You may try something like this:
const staff = [
{
user: '245569534218469376',
text: 'dev'
},
{
user: '294597887919128576',
text: 'loner'
}
];
let item = staff.find(item => item.user == '294597887919128576'); // msg.member.id
if (item) {
console.log(item.text);
}
One another way to do that is:
const inArray = (array, id) => array.filter(item => item.user === id).length >= 1;
const users = [
{
user: '245569534218469356',
text: 'foo'
}, {
user: '245564734218469376',
text: 'bar'
}, {
user: '246869534218469376',
text: 'baz'
}
];
console.log(inArray(users, '246869534218469376')); // true
console.log(inArray(users, '222479534218469376')); // false

restructure json based on parent

I am studying the use of reduce in javascript, and I am trying to restructure an Array of Objects in a generic way - need to be dynamic.
flowchart - i get totaly lost
I started with this through.
Every ID becomes a Key.
Every PARENT identifies which Key it belongs to.
i have this:
const in = [
{
"id": "Ball",
"parent": "Futebol"
},
{
"id": "Nike",
"parent": "Ball"
},
{
"id": "Volley",
"parent": null
}
]
i want this
out = {
"Futebol": {
"Ball": {
"Nike": {}
}
},
"Volley": {}
}
i try it - and i had miserably failed.
const tree = require('./mock10.json')
// Every ID becomes a Key.
// Every PARENT identifies which Key it belongs to.
const parsedTree = {}
tree.reduce((acc, item) => {
if (parsedTree.hasOwnProperty(item.parent)){
if (parsedTree[`${item.parent}`].length > 0) {
parsedTree[`${item.parent}`][`${item.id}`] = {}
} else {
parsedTree[`${item.parent}`] = { [`${item.id}`]: {} }
}
} else {
// i get lost in logic
}
}, parsedTree)
console.log(parsedTree)
Got a working code for you, feel free to ask me about the implementation
Hope it helps :)
const arrSample = [
{
"id": "Ball",
"parent": "Futebol"
},
{
"id": "Nike",
"parent": "Ball"
},
{
"id": "Volley",
"parent": null
}
]
const buildTree = (arr) => {
return arr.reduce(([tree, treeMap], { id, parent }) => {
const val = {}
treeMap.set(id, val)
if (!parent) {
tree[id] = val
return [tree, treeMap]
}
if (!treeMap.has(parent)) {
const parentVal = { [id]: val }
treeMap.set(parent, parentVal)
tree[parent] = parentVal
return [tree, treeMap]
}
const newParentValue = treeMap.get(parent)
newParentValue[id] = val
treeMap.set(parent, newParentValue)
return [tree, treeMap]
}, [{}, new Map()])
}
const [result] = buildTree(arrSample)
console.log(JSON.stringify(result, 0, 2))
You could use reduce method for this and store each id on the first level of the object. This solution will work if the objects in the array are in the correct order as in the tree structure.
const data = [{"id":"Futebol","parent":null},{"id":"Ball","parent":"Futebol"},{"id":"Nike","parent":"Ball"},{"id":"Volley","parent":null}]
const result = data.reduce((r, { id, parent }) => {
if (!parent) {
r[id] = {}
r.tree[id] = r[id]
} else if (r[parent]) {
r[parent][id] = {}
r[id] = r[parent][id]
}
return r
}, {tree: {}}).tree
console.log(result)
If reduce solution is just an option, you can try this way:
var input = [
{
"id": "Ball",
"parent": "Futebol"
},
{
"id": "Nike",
"parent": "Ball"
},
{
"id": "Volley",
"parent": null
}
];
var output = {};
input.forEach(item => {
var temp = input.find(x => x.id === item.parent);
if (temp) {
temp[item.id] = {};
}
});
input = input.filter(item => !input.find(x => x.hasOwnProperty(item.id)));
input.forEach(item => {
if (!item.parent) {
output[item.id] = {};
} else {
for (var [id, value] of Object.entries(item)) {
if (typeof value === 'object') {
output[item.parent] = { [item.id]: { id: {} } };
}
}
}
})
console.log(output);
I have tried many things, but none works if we use an Array.prototype.reduce
As there are missing parents, and the elements are out of order, plus the fact that there can be an infinity of levels, I really do not believe that this question can be resolved with a simple reduce
This code should work whatever the cases :
- if all parents are not declared
- if there are infinitely many levels
- if they are in disorder
const origin =
[ { id: 'Ball', parent: 'Futebol' }
, { id: 'Nike', parent: 'Ball' }
, { id: 'Volley', parent: null }
, { id: 'lastOne', parent: 'level4' } // added
, { id: 'level4', parent: 'Nike' } // added
, { id: 'bis', parent: 'Nike' } // added
];
const Result = {} // guess who ?
, Parents = [] // tempory array to keep parents elements address by key names
;
let nbTodo = origin.length // need this one to verify number of elements to track
;
// set all the first levels, add a todo flags
origin.forEach(({id,parent},i,ori)=>
{
ori[i].todo = true // adding todo flag
if (parent===null)
{
Result[id] = {} // new first level element
ori[i].todo = false // one less :)
nbTodo--
Parents.push(({ref:id,path:Result[id]}) ) // I know who you are!
}
else if (origin.filter(el=>el.id===parent).length===0) // if he has no parent...
{
Result[parent] = {} // we create it one
Parents.push({ref:parent,path:Result[parent]} )
}
})
// to put the children back in their parents' arms
while(nbTodo>0) // while there are still some
{
origin.forEach(({id,parent,todo},i,ori)=> // little by little we find them all
{
if(todo) // got one !
{
let pos = Parents.find(p=>p.ref===parent) // have parent already been placed?
if(pos)
{
ori[i].todo = false // to be sure not to repeat yourself unnecessarily
nbTodo-- // one less :)
pos.path[id] = {} // and voila, parentage is done
Parents.push(({ref:id,path:pos.path[id]}) ) // he can now take on the role of parent
}
}
})
}
for (let i=origin.length;i--;) { delete origin[i].todo } // remove todo flags
console.log( JSON.stringify(Result, 0, 2) )
.as-console-wrapper { max-height: 100% !important; top: 0; }
I finaly made this one, based on this previous on, and done with a first step by a reduce...
to by pass the Array of Parents, I made a recursive function for searching each parent elements thru the levels of parsedTree result.
here is the code:
const Tree =
[ { id: 'Ball', parent: 'Futebol' }
, { id: 'Nike', parent: 'Ball' }
, { id: 'Volley', parent: null }
, { id: 'lastOne', parent: 'level4' } // added
, { id: 'level4', parent: 'Nike' } // added
, { id: 'bis', parent: 'Nike' } // added
];
const parsedTree = Tree.reduce((parTree, {id,parent},i ) => {
Tree[i].todo = false
if (parent===null)
{ parTree[id] = {} }
else if (Tree.filter(el=>el.id===parent).length===0) // if he has no parent...
{ parTree[parent] = { [id]: {} } }
else
{ Tree[i].todo = true }
return parTree
}, {})
function parsedTreeSearch(id, part) {
let rep = null
for(let kId in part) {
if (kId===id)
{ rep = part[kId] }
else if (Object.keys(part[kId]).length)
{ rep = parsedTreeSearch(id, part[kId]) }
if (rep) break
}
return rep
}
while (Boolean(Tree.find(t=>t.todo))) {
Tree.forEach(({id,parent,todo},i)=>{ // little by little we find them all
if (todo) {
let Pelm = parsedTreeSearch(parent, parsedTree)
if (Boolean(Pelm)) {
Pelm[id] = {}
Tree[i].todo = false
} } }) }
for (let i=Tree.length;i--;) { delete Tree[i].todo } // remove todo flags
console.log( JSON.stringify( parsedTree ,0,2))
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to validate deeply nested object structure

I have defined object with nested properties. I want to create a validator function which will check if another object has the same structure and value type as the one that I have defined!
The is the definition of the object:
const OBJECT_SCHEMA = {
name: String,
data: [{
isSelected: Boolean,
mId: String,
mSummary: String,
mMarkets: Array,
mBdd: String,
mReplaceDict: Object,
omId: String,
omnSummary: String,
omnMarkets: Array,
omnBdd: String,
omnReplaceDict: {
id: String,
text: String,
},
}],
metadata: {
emails: Array,
description: String,
},
};
And here is the function that I have for validation. Currently it works only with one nested level! I want it to validate with many nested levels.
function validateObjectStructure(schema, obj) {
let valid = true;
firstLevel: for(const k in schema) {
if(schema[k].constructor === Array) { // if prop is of type array
let i;
for(i = 0; i < schema[k].length; i++) {
for(const kk in schema[k][i]) {
if(!obj[k][i].hasOwnProperty(kk) || obj[k][i][kk].constructor !== schema[k][i][kk]) {
valid = false;
break firstLevel;
}
}
}
}
else if(schema[k].constructor === Object) { // if prop is of type object
for(const kk in schema[k]) {
if(!obj[k].hasOwnProperty(kk) || obj[k][kk].constructor !== schema[k][kk]) {
valid = false;
break firstLevel;
}
}
}
else { // if prop is simple type
if(!obj.hasOwnProperty(k) || obj[k].constructor !== schema[k]) {
valid = false;
break;
}
}
}
return valid;
}
Do you need to work with nested levels of the obj? If yes, you can do something like this instead of the last line:
Object.values(obj).reduce((accValid, value) => {
if (typeof value === 'object') {
return accValid && validateObjectStructure(schema, value);
}
return accValid;
}, valid);
return valid;
Here's a possible implementation:
function validate(obj, schema, path = '') {
let ok = true;
if (!obj)
ok = obj === schema;
else if (typeof schema === 'function')
ok = obj.constructor === schema;
else if (typeof obj !== 'object')
ok = obj === schema;
else if (Array.isArray(schema))
ok = Array.isArray(obj) && obj.every((x, k) => validate(x, schema[0], path + '[' + k + ']'));
else {
let ko = Object.keys(obj);
let ks = Object.keys(schema);
ok = ko.length === ks.length && ks.every(k => validate(obj[k], schema[k], path + '.' + k));
}
if (!ok)
throw new Error('FAILED ' + path);
return true;
}
// example:
const OBJECT_SCHEMA = {
name: String,
data: [{
isSelected: Boolean,
mId: String,
omnReplaceDict: {
id: String,
text: {
deepObj: {
deepProp: [Number]
}
},
},
}],
};
const obj = {
name: "foo",
data: [{
isSelected: true,
mId: "bar",
omnReplaceDict: {
id: "foo",
text: {
deepObj: {
deepProp: [1, 2, "???", 3]
}
},
},
}]
};
validate(obj, OBJECT_SCHEMA)
Note: although this home-made type checker appears to work correctly, it's quite limited (e.g. how to express "array of string-number pairs" or "either null or some object"?), so it might be an option to employ a real one, like Typescript. See here for a possible implementation.

How to pass video node from resolve/database to node definitions in graphql relay?

My node definitions looks like this:
class Store {}
let store = new Store()
let nodeDefs = nodeDefinitions(
(globalId) => {
let type = fromGlobalId(globalId).type
let id = fromGlobalId(globalId).id
if (type === 'Store') {
return store
}
if (type === 'Video') {
return docClient.query(
Object.assign(
{},
{TableName: videosTable},
{KeyConditionExpression: 'id = :id'},
{ExpressionAttributeValues: { ':id': id }}
)
).promise().then(dataToConnection)
}
return null
},
(obj) => {
if (obj instanceof Store) {
return storeType
}
if (obj instanceof Video) {
return videoType
}
return null
}
)
The problem is that video node is always null, even when actual video is being returned from the database, because for it to not be null I need to look it up based on id or somehow fetch it from database.
This is the video node I am referring to:
video: {
type: videoType,
args: Object.assign(
{},
connectionArgs,
{id: {type: GraphQLString}}
),
resolve: (_, args) => {
return docClient.query(
Object.assign(
{},
{TableName: pokemonTable},
{KeyConditionExpression: 'id = :id'},
{ExpressionAttributeValues: { ':id': args.id }},
paginationToParams(args)
)
).promise().then(dataToConnection)
}
},
and
const videoType = new GraphQLObjectType({
name: 'Video',
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLID),
resolve: (obj) => obj.id
},
name: { type: GraphQLString },
url: { type: GraphQLString }
}),
interfaces: [nodeDefs.nodeInterface]
})
const allVideosConnection = connectionDefinitions({
name: 'Video',
nodeType: videoType
})
I tried doing database query directly inside node definitions, but that didn't work.
dataToConnection just converts the output of dynamoDB:
video DATA!! { Items:
[ { id: 'f4623d92-3b48-4e1a-bfcc-01ff3c8cf754',
url: 'http://www.pokkentournament.com/assets/img/characters/char-detail/detail-pikachuLibre.png',
name: 'YAHOO' } ],
Count: 1,
ScannedCount: 1 }
into something that graphql relay understands:
video dataToConnection!! { edges:
[ { cursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
node: [Object] } ],
pageInfo:
{ startCursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
endCursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
hasPreviousPage: false,
hasNextPage: false } }
and the function itself can be found here: https://github.com/dowjones/graphql-dynamodb-connections/pull/3/files
It could be the problem.
Also, asking/querying for id makes the whole video object null:
But omitting id from the query returns something, whether querying with relay id:
or database id
and querying for all of the videos works:
The interesting part is that I get exactly same problem even if I delete the video part from node definitions:
let nodeDefs = nodeDefinitions(
(globalId) => {
let type = fromGlobalId(globalId).type
let id = fromGlobalId(globalId).id
if (type === 'Store') {
return store
}
return null
},
(obj) => {
if (obj instanceof Store) {
return storeType
}
return null
}
)
Any ideas?
UPDATE:
I did some digging and found that interfaces in fact is undefined
const storeType = new GraphQLObjectType({
name: 'Store',
fields: () => ({
id: globalIdField('Store'),
allVideosConnection: {
type: allVideosConnection.connectionType,
args: Object.assign(
{},
connectionArgs
),
resolve: (_, args) => {
return docClient.scan(
Object.assign(
{},
{TableName: pokemonTable},
paginationToParams(args)
)
).promise().then(dataToConnection)
}
},
video: {
type: videoType,
args: Object.assign(
{},
connectionArgs,
{id: {type: GraphQLString}}
),
resolve: (_, args) => {
return docClient.query(
Object.assign(
{},
{TableName: pokemonTable},
{KeyConditionExpression: 'id = :id'},
{ExpressionAttributeValues: { ':id': args.id }},
paginationToParams(args)
)
).promise().then(dataToConnection)
}
}
}),
interfaces: [nodeDefs.nodeInterface]
})
console.dir(storeType.interfaces, { depth: null })
prints undefined
Why? I clearly define them at the top!
Also, I can do that:
But this doesn't work:
This is what is being returned in video: {} resolve:
{ edges:
[ { cursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
node:
{ id: 'f4623d92-3b48-4e1a-bfcc-01ff3c8cf754',
url: 'http://www.pokkentournament.com/assets/img/characters/char-detail/detail-pikachuLibre.png',
name: 'YAHOO' } } ],
pageInfo:
{ startCursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
endCursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
hasPreviousPage: false,
hasNextPage: false } }
Somehow that's okay for allVideosConnection, but not okay (ends up null) for video
Do I need to convert ids of nodes to global IDs? using toGlobalId ? Just for video ?
Because another thing I noticed is that if I
console.log('fromGlobalId', fromGlobalId(globalId))
inside my node definitions, this query:
{
node(id: "f4623d92-3b48-4e1a-bfcc-01ff3c8cf754") {
id
...F1
}
}
fragment F1 on Video {
url
name
}
becomes this:
fromGlobalId { type: '', id: '\u000e6]_v{vxsn\u001eU/\u001b}G>SW_]O\u001c>x' }
However, if I do
I get
globalId U3RvcmU6
fromGlobalId { type: 'Store', id: '' }
So to make node definitions work, all I had to do was this:
class Video {}
let video = new Video()
return Object.assign(video, data.Items[0])
i.e. create class with the same name as type name
and then Object.assign to it
Just doing this, doesn't work:
return {Video: data.Items[0]}
I also need to create IDs in the database like that: Video:f4623d92-3b48-4e1a-bfcc-01ff3c8cf754, where I am essentially putting type and randomly generated unique id together separated by a colon (:) and then encode it with toGlobalId function of graphql-relay-js library (so I end up with VmlkZW86ZjQ2MjNkOTItM2I0OC00ZTFhLWJmY2MtMDFmZjNjOGNmNzU0Og==), so then I can decode it with fromGlobalId so that node definitions can retrieve both type and id({ type: 'Video', id: 'f4623d92-3b48-4e1a-bfcc-01ff3c8cf754:' }), after which I still need to add fromGlobalId(globalId).id.replace(/\:$/, '')) to remove the trailing colon (:).
`
Also, interfaces are not meant to be accessible, they are just for configuration.

Categories