Discussion on: What are you struggling with? (frontend)

octaneinteractive profile image
Wayne Smallman

I didn't want to go into too much detail in case you weren't interested.

First, I have to parse the data into edges and nodes. Then, I use a recursive function:

services.acyclicalBuildingOfGraph = (userID, noteID, visited = [], depth = 0, maxDepth = 5) => { ... }

... to cycle through each node, exploring each link in turn to maxDepth.

In PHP, this is simple, but in JavaScript, it's proving to be a major problem.

Thread Thread
andi23rosca profile image
Andi Rosca Author

I'm still not quite sure where the problem lies. Is it the recursivity? Maybe if you can share the exact piece of code where stuff strats to break down?

Thread Thread
octaneinteractive profile image
Wayne Smallman

First, assetGraph() is called, via the API:

'use strict'

let services = {}

// Notes.

const Notes = require('../models/notes')

let graph = {
  nodes: [],
  edges: []

// Methods.

services.assetGraph = async (params) => {

  if (graph.nodes.length > 0)
    graph.nodes = []

  if (graph.edges.length > 0)
    graph.edges = []

  const acyclicalGraph = await services.acyclicalBuildingOfGraph(params.userID, params.noteID)

  console.log("Perspective:assetGraph()", graph)

  return acyclicalGraph


services.acyclicalBuildingOfGraph = (userID, noteID, visited = [], depth = 0, maxDepth = 5) => {

  console.log("Perspective:acyclicalBuildingOfGraph()", userID, noteID, visited, depth, maxDepth)

  return new Promise((resolve, reject) => {

    userID = parseInt(userID)
    noteID = parseInt(noteID)

    if ( depth > maxDepth )

    if ( visited.includes(noteID) )

      id: noteID
    }).then(asset => {

      let assetInQuestion = asset[0].dataValues

        user_id: userID,
        note_id: noteID
      }).then(linksTo => {

          data: {
            id: parseInt(noteID),
            creation: assetInQuestion.creation,
            modification: assetInQuestion.modification,
            title: assetInQuestion.title,
            depth: depth,
            weight: (maxDepth - depth)

        // console.log("Perspective:acyclicalBuildingOfGraph():node", graph.nodes.length)

        if ( linksTo.length > 0 ) {

          let assetsLinkedTo = linksTo[0].dataValues.NotesLinksFrom

          let i = assetsLinkedTo.length

          assetsLinkedTo.forEach(async link => {

            // console.log("Perspective:acyclicalBuildingOfGraph():iteration", i)

            let linkedNoteId = link.to_asset

            let edgeID = `${noteID}->${linkedNoteId}`

            if ( services.findDuplicateEdgeId('id', edgeID) === false ) {

                data: {
                  id: edgeID,
                  weight: (maxDepth - depth),
                  source: parseInt(noteID),
                  target: parseInt(linkedNoteId)


            await services.acyclicalBuildingOfGraph(userID, linkedNoteId, visited, depth + 1)


          // console.log(`Perspective:acyclicalBuildingOfGraph():graph:${depth}:`, graph.edges)

          return resolve(graph)






services.getAsset = (params) => {
  return Notes.getAsset(params)

services.getLinksToAsset = (params) => {
  return Notes.getLinksToAsset(params)

services.findDuplicateEdgeId = (field, value) => {

  // console.log("Perspective:findDuplicateEdgeId()", edges)

  if ( graph.edges.length > 0 ) {
    for (const [index, edge] of Object.entries(graph.edges)) {

      // console.log("Perspective:findDuplicateEdgeId():for", index, edge)

      if (edge[field] === value) {
        return index

  return false


module.exports = services
Thread Thread
andi23rosca profile image
Andi Rosca Author

I think stuff starts to break down because you return inside the Promise in services.acyclicalBuildingOfGraph. If you don't call resolve or reject in a Promise it will never actually finish.

The problems I see are mostly around the confusion with async code in javascript. I'm assuming you need to use async code because Notes.getLinksToAsset(params) or similar calls are fetching stuff?

Async/await syntax is just syntactical sugar over promises, meaning that when you create an async function, it actually creates a function that returns a promise "under the hood". And when you say return inside of an async function it's like calling the resolve function of the Promise. But it doesn't automatically resolve normal promises.

I'd say you should put empty resolve() statements right before your returns, so that the Promise will actually finish. You can also just do resolve(graph) instead of return resolve(graph).
And at least your code should execute. You can take it from there and see if it actually does what it's supposed to do.

Thread Thread
octaneinteractive profile image
Wayne Smallman

I've narrowed it down to something in Vue rather than Node

Andi, thanks for the time, much appreciated.