1
\$\begingroup\$

This is the backend "API" in Socket.io for my links/bookmarks app. Error handling in this and verifying a path to the link seems pretty verbose. I want to improve this.

const User = require('../models/user')
const utils = require('../utils')
var linkify = require('linkifyjs')
require('linkifyjs/plugins/hashtag')(linkify) // optional

module.exports = function(socket, io) {
  function getLinks(data, socket) {
    User.findOne({ username: data.username }, function(err, user) {
      if (err) {
        return socket.emit('throw', 'Database error')
      }
      if (!user) {
        return socket.emit('throw', 'User not found')
      }
      if (!data.collection) {
        return socket.emit('throw', 'No collection provided.')
      }
      var collectionIndex = user.links.findIndex(
        collection => data.collection === collection.name
      )
      if (collectionIndex === -1) {
        return socket.emit('throw', 'Collection not found')
      }
      if (user.links[collectionIndex]) {
        console.log('Success getting links')
        return socket.emit('updateLinks', user.links[collectionIndex])
      } else {
        return socket.emit('updateLinks', [])
      }
    })
  }
  socket.on('joinLinksRoom', function(data) {
    socket.leave(socket.activeRoom)
    var newRoom = `${data.username}-${data.collection}`
    socket.join(newRoom)
    socket.activeRoom = newRoom
    getLinks(data, socket)
  })
  socket.on('leaveLinksRoom', function(data) {
    socket.leave(socket.activeRoom)
  })
  socket.on('createLink', function(data) {
    if (socket.userInfo) {
      User.findOne({ googleId: socket.userInfo.googleId }, function(err, user) {
        if (err) {
          return socket.emit('throw', 'Database error')
        }
        if (!user) {
          return socket.emit('throw', 'User not found')
        }
        var collection = data.collection
        var link = data.link
        var category = data.category
        if (!collection || !link || !category) {
          return socket.emit('throw', 'Data missing')
        }
        if (!link.linkUrl) {
          return socket.emit('throw', 'No link URL provided')
        }
        if (!link.linkName) {
          link.linkName = link.linkUrl
        }
        var foundLinks = linkify.find(link.linkUrl)[0]
        if (foundLinks) {
          link.linkUrl = linkify.find(link.linkUrl)[0].href
        }
        link.id = utils.general.uuid()
        var collectionIndex = user.links.findIndex(
          foundCollection => foundCollection.name === collection
        )
        if (collectionIndex === -1) {
          return socket.emit('throw', 'Collection not found')
        }
        var colObject = user.links[collectionIndex]
        var categoryIndex = colObject.categories.findIndex(
          foundCategory => foundCategory.name === category
        )
        if (categoryIndex === -1) {
          colObject.categories.push({
            name: category,
            links: []
          })
          categoryIndex = colObject.categories.findIndex(
            foundCategory => foundCategory.name === category
          )
        }
        var catObject = colObject.categories[categoryIndex]
        catObject.links.push(link)
        user.save(function(err, newUser) {
          if (err) {
            console.log(err)
            return socket.emit('throw', 'Database error')
          }
          console.log('Success adding link')
          var targetRoom = `${socket.userInfo.username}-${data.collection}`
          return io
            .in(targetRoom)
            .emit('updateLinks', newUser.links[collectionIndex])
        })
      })
    } else {
      return socket.emit('throw', 'Not logged in')
    }
  })
  socket.on('deleteLink', function(data) {
    if (socket.userInfo) {
      User.findOne({ googleId: socket.userInfo.googleId }, function(err, user) {
        if (err) {
          return socket.emit('throw', 'Database error: ' + err)
        }
        var pId = data.id
        var pCategory = data.category
        var pCollection = data.collection
        if (!pId || !pCategory || !pCollection) {
          return socket.emit('throw', 'Missing id, category or collection')
        }
        var collectionIndex = user.links.findIndex(
          foundCollection => foundCollection.name === pCollection
        )
        if (collectionIndex === -1) {
          return socket.emit('throw', 'Collection not found')
        }

        var categoryIndex = user.links[collectionIndex].categories.findIndex(
          foundCategory => foundCategory.name === pCategory
        )
        if (categoryIndex === -1) {
          return socket.emit('throw', 'Category not found')
        }

        var pathToCat =
          user.links[collectionIndex].categories[categoryIndex].links

        var linkIndex = pathToCat.findIndex(link => link.id === pId)
        if (linkIndex === -1) {
          return socket.emit('throw', 'No link with id found')
        }
        pathToCat.splice(linkIndex, 1)

        if (pathToCat.length === 0) {
          user.links[collectionIndex].categories.splice(categoryIndex, 1)
        }
        user.save(function(err, newUser) {
          if (err) {
            return socket.emit('throw', 'Database error: ' + err)
          }
          io
            .in(`${socket.userInfo.username}-${data.collection}`)
            .emit('updateLinks', newUser.links[collectionIndex])
        })
      })
    } else {
      socket.emit('throw', 'Not logged in')
    }
  })
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.