0
var yModule = require('youtube-node'),
    nodeYoutube = new yModule();

nodeYoutube.setKey("key");

module.exports.getVideoLength = function (vData){
    youTube.getById(vData, function (result) {
        return convertTime(result['items'][0]['contentDetails']['duration']);
    })
};

var convertTime = function (time){
    var reptms = /(?:(\d+)DT)?(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?$/;
    var days = "00", hours = "00", minutes = "00", seconds = "00", formattedTime;


    //if (reptms.test(time)) {
        var matches = reptms.exec(time);
        console.log(matches);
        if (matches[1]) days = String(matches[1]);
        if (matches[2]) hours = String(matches[2]);
        if (matches[3]) minutes = String(matches[3]);
        if (matches[4]) seconds = String(matches[4]);
        formattedTime = "[" + days + ":" + hours + ":" + minutes + ":" + seconds + "]";
        return formattedTime;
    //}
};

I'm struggling to understand callbacks even after reading a few things about it. nodeJs callbacks simple example this helped a little, but I'm still unclear about how it works. I've spent the past hour trying to figure out how to write this using callbacks.

This module is being called by this:

 ytRetrieve.getVideoLength(youtube_parser(text))

youtube_parser's function:

function youtube_parser(url){
    var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
    var match = url.match(regExp);
    //console.log(match);
    if (match&&match[7]){
        return match[7].split(" ")[0];
    }
}
Community
  • 1
  • 1
ECMAScript
  • 4,439
  • 4
  • 21
  • 29
  • What is `bot`? Did you create this or is it some other module? – Explosion Pills Dec 27 '14 at 00:11
  • @ExplosionPills it's the 'irc' module – ECMAScript Dec 27 '14 at 03:01
  • This is hilarious. Username "ECMAScript" asking if callbacks are necessary :) Short answer: yes, always, especially in node. Here's a great [resource on callbacks](http://javascriptissexy.com/understand-javascript-callback-functions-and-use-them/) to help you wrap your head around them. Cheers! – Keenan Lidral-Porter Dec 27 '14 at 06:42

2 Answers2

0

You need to use callbacks. The issue with your code youtube_parser( is that you are calling the function. A callback is a function that is passed as an argument to be called later. If you call the function, a string is returned. getVideoLength is expecting a function as an argument, not a string.

Instead use getVideoLength(youtube_parser). This actually passes in the youtube_parser function itself to be called later (i.e. when getVideoLength completes). The arguments to youtube_parser may need to be (error, url) instead, though.

Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
  • " A callback is a function that is passed as an argument to be called later." I don't understand this. And what do I do with the error parameter? I'm trying to call getVideoLength after youtube_parser returns a value. – ECMAScript Dec 26 '14 at 03:39
  • Updated with a solution I tried that gives me a undefined is not a function error – ECMAScript Dec 26 '14 at 03:57
  • @ECMAScript what don't you understand about it? You can pass a string, an integer, or a boolean as an argument. Why not a function? – Explosion Pills Dec 27 '14 at 00:12
0

Here is a solution I came up with. Is there anything I can do to enhance this code?

Thank you for your help.

Main.js

var ytempRetrieve = require('./youtube'), ytRetrieve = new ytempRetrieve();

var ytRegex = /(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?/;


bot.addListener('message', function (from, to, text, message) {
    if (text.match(ytRegex)) {
        console.log(text);
        youtube_parser(text, to, ytRetrieve.getVideoLength)
    }
});

function youtube_parser(url, to, callback) {
    var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
    var match = url.match(regExp);
    //console.log(match);
    if (match && match[7]) {
        callback(match[7].split(" ")[0], function (res) {
            setTimeout(function () {
                bot.say(to, match[7].split(" ")[0] + " is " + res + " long.")
            }, 1500)
        });
    }
}

youtube.js

var yModule = require('youtube-node'),
    nodeYoutube = new yModule(),
    apiKey = require('./config');


    var youtube = function () {
    var self = this;

    self.time = null;

    self.setAPIKey = function (key) {
        nodeYoutube.setKey(key);
    };

    apiKey.getAPIKey(self.setAPIKey);

    self.getVideoLength = function (vData, callback) {
        nodeYoutube.getById(vData, function (result) {
            callback(self.convertTime(result['items'][0]['contentDetails']['duration']));
        })
    };

    self.convertTime = function (time) {
        var reptms = /(?:(\d+)DT)?(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?$/;
        var days = 0, hours = 0, minutes = 0, seconds = 0, formattedTime;

        //if (reptms.test(time)) {
        var matches = reptms.exec(time);
        console.log(matches);
        if (matches[1]) days = Number(matches[1]);
        if (matches[2]) hours = Number(matches[2]);
        hours += days * 24;
        if (hours.toString().length === 1) {
            hours = "0" + hours
        }
        if (matches[3]) minutes = String(matches[3]);
        if (minutes.toString().length === 1) {
            minutes = "0" + minutes
        }
        if (matches[4]) seconds = String(matches[4]);
        if (seconds.toString().length === 1) {
            seconds = "0" + seconds
        }
        formattedTime = "[" + hours + ":" + minutes + ":" + seconds - 1 + "]";
        return (formattedTime);
        //}
    };

};

module.exports = youtube;
ECMAScript
  • 4,439
  • 4
  • 21
  • 29