12 Replies - 470 Views - Last Post: 05 September 2013 - 03:48 PM

#1 Arenlor  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 34
  • View blog
  • Posts: 389
  • Joined: 26-April 06

Variable not available in children

Posted 05 September 2013 - 04:33 AM

Hi, I'm trying to edit hangoutonair.js to reload when a stream goes live. The code as I have it currently is:
/**
 * Title: Youtube Live Player (StaticHangouts)
 * Descriptions: Allows you to auto-embed your latest live broadcast
 * Developers: Robert Pitt, Moritz Tolxdorff.
 * Contact: Robert PItt <https://plus.google.com/110106586947414476573>
 * Contact: Moritz Tolxdorf <https://plus.google.com/117596712775912423303>
 *
 * Copyright: (C) 2012 Robert Pitt, Moritz Tolxdorff
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
(function(){
    /**
     * Boolean to deter if Dom has loaded
     * @private
    */
    var readyLoad_ = false;


    /**
     * @constructor
    */
    var HOAPlayer = function()
    {
        /**
         * Configuration Stack, can be modified by the main window
        */
        this.config = {
            defaultWidth : 560,
            defaultHeight : 315,
            playerFrameBorder : 0,
            allowFullScreen : true
        };

        /**
         * Merge the configuration object with any potential overwrites
        */
        this.config = this.mergeObjects(this.config, window["_hoa_config"] || {});

        /**
         * Bind documentReady event
        */
        this.bindonload(this.onDomLoaded.bind(this));
    };

    /**
     * Callback fired when DOM is ready
    */
    HOAPlayer.prototype.onDomLoaded = function(e)
    {
        /**
         * Scan the DOM for all the elements that have the classname onair
        */
        var targets = document.getElementsByClassName('onair'), i;

        /**
         * Loop the targets and draw a video feed
        */
        for(i = 0; i < targets.length; i++)
        {
            /**
             * only apply the player if there is a data-uid attribute
            */
            if(targets[i].getAttribute('data-uid'))
            {
                var uid = targets[i].getAttribute('data-uid');
                var width = targets[i].getAttribute('data-width') || this.config.defaultWidth;
                var height = targets[i].getAttribute('data-height') || this.config.defaultHeight;

                /**
                 * Start the call for this element
                */
                this.loadVideoPlayer(targets[i], uid, width, height);
            }
        }
    }

    /**
     * Loads a video player form feed
     * @param target {Element} Target Element.
     * @param uid {String} Username of the feed
     * @param width {Number} width of the player
     * @param height {Number} height of the player
    */
    HOAPlayer.prototype.loadVideoPlayer = function(target, uid, width, height)
    {
        /**
         * Fetch the latest json feed for the current user
        */
        this.fetchUserFeed(uid, 0, function(err, feed){

            /**
             * Get the last entry of the feed
            */
            var feed = feed.feed.entry;
            if(feed){
                for(var i = 0 ; i < feed.length; i++){
                    if(feed[i]["yt$status"]["$t"] == "active"){
                        var entry = feed[i];
                    }
                }
                /**
                 * If there is an entry, parse the required information
                */
                if(entry && entry.content)
                {
                    /**
                     * Parse the URL and split it into segments to get the last entity
                    */
                    var UrlParts = entry.content.src.split("/");

                    /**
                     * Create an iframe
                    */
                    var iframe = document.createElement('iframe');

                    /**
                     * Assign the param to the iframe
                    */
                    iframe.src = 'http://www.youtube.com/embed/' + UrlParts[UrlParts.length-1].split("?")[0] + '?autoplay=1';
                    iframe.width = width;
                    iframe.height = height;
                    iframe.setAttribute("frameborder", this.config.playerFrameBorder);
                    iframe.setAttribute("allowfullscreen", this.config.allowFullScreen);

                    /**
                     * Replace the target node with the iframe node
                    */
                    target.parentNode.replaceChild(iframe, target);
                }
            }else{
                /**
                 * Refresh the page around when it should be live
                */
                var curTime = new Date();
                if(/*(curTime.getUTCHours() >=2 && curTime.getUTCHours() <=6) &&*/ curTime.getUTCDay() == 4) {
                    var updateWarn = document.getElementById("istwislive");
                    updateWarn.innerHTML="TWIS will be live any time now. Refreshing the page when live.";
                    var checkLive=self.setInterval(function(){rechecklive();},30000);
                    function rechecklive() {
                        for(var i=0; i<feed.length; i++) {if(feed[i]['yt$status']['$t'] == 'active') {location.reload();}}
                    }
                }
                this.fetchUserFeed(uid, 1, function(err, feed){
                    
                    var entry = feed.feed.entry;
                   // console.log(feed);
                    /**
                     * If there is an entry, parse the required information
                    */
                    if(entry)
                    {   
                        console.log(entry[0].id["$t"]);
                        /**
                         * Parse the URL and split it into segments to get the last entity
                        */
                        var UrlParts = entry[0].id["$t"].split("/");
                        /**
                         * Create an iframe
                        */
                        var iframe = document.createElement('iframe');

                        /**
                         * Assign the param to the iframe
                        */
                        iframe.src = 'http://www.youtube.com/embed/' + UrlParts[5];
                        iframe.width = width;
                        iframe.height = height;
                        iframe.setAttribute("frameborder", this.config.playerFrameBorder);
                        iframe.setAttribute("allowfullscreen", this.config.allowFullScreen);

                        /**
                         * Replace the target node with the iframe node
                        */
                        target.parentNode.replaceChild(iframe, target);
                    }
                }.bind(this));
            }
        }.bind(this));
    }
    
    /**
     * Fetches a JSON Object from youtube for a specified uid
     * @param uid {String} Username of the feed
     * @param callback {Function(e, feed)} callback to be called
    */
    HOAPlayer.prototype.fetchUserFeed = function(uid, flag, callback)
    {
        /**
         * Create a random function to assign to the global scope
        */
        var magic = '__YTLiveStreams_' + uid + "_" + Math.floor(Math.random() * 1000001);
        /**
         * Apply the callback to the root object (window)
        */
        this.awaitLoadResonse(magic, callback);

        /**
         * Build the URL
        */
        if(flag == 0){
            var URL = "https://gdata.youtube.com/feeds/api/users/" + uid + "/live/events?v=2&alt=json&status=active&callback=" + magic;
            //console.log(URL);
        }
        if(flag == 1){
            var URL = "http://gdata.youtube.com/feeds/users/" + uid + "/uploads?alt=json&max-results=1&callback=" + magic;
            //console.log(URL);
        }
        /**
         * Create an script element to append to the head
        */
        var re = document.createElement('script');
        re.type = 'text/javascript';
        re.async = true;
        re.src = URL;

        /**
         * Prepend the element to the head of the document.
        */
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(re, s);
    }

    HOAPlayer.prototype.awaitLoadResonse = function(magic, callback)
    {
        window[magic] = function(payload)
        {
            /**
             * Here, I would like to do some error checking but not required
            */
            callback(null, payload);
        }
    }

    /**
     * Bind DOMReady callbacks to the dom (cross-browser)
     * @param callback {Function}, callback to be fired
     * @see https://github.com/dperini/ContentLoaded/blob/master/src/contentloaded.js
     * @see http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
    */
    HOAPlayer.prototype.bindonload = function(callback)
    {
        /**
         * If the dom is already laoded just call the callback inline
        */
        if(readyLoad_ == true)
        {
            callback();
        }

        //Mozzilla, Opera and webkit support addEventListener
        if(document.addEventListener)
        {
            document.addEventListener( "DOMContentLoaded", function(){
                callback();
                readyLoad_ = true;
            }, false);

            return;
        }

        //IE
        if(document.attachEvent)
        {
            document.attachEvent("onreadystatechange", function(){
                if (document.readyState === "complete" ) {
                    callback();
                    readyLoad_ = true;
                }
            });

            return;
        }

        //Fallback to window.onload
        window.onload = callback;
    }

    /**
     * Merges {n} objects into a new object, i
     * @param * {Object}, Objects to be merged
    */
    HOAPlayer.prototype.mergeObjects = function()
    {
        var buildObject = {}, i, e;

        /**
         * Loop arguments, {obj1, obj2, obj3, ...}
        */
        for(i = 0; i < arguments.length; i++)
        {
            /**
             * Loop attributes of the current object
            */
            for(e in arguments[i])
            {
                /**
                 * Pass the key and value of the current object into the builldObject
                */
                buildObject[e] = arguments[i][e];
            }
        }

        return buildObject;
    }

    /**
     * Export an instantiated instance
    */
    window["_hoa_instance_"] = new HOAPlayer();
})()


This issue is:
                var curTime = new Date();
                if(/*(curTime.getUTCHours() >=2 && curTime.getUTCHours() <=6) &&*/ curTime.getUTCDay() == 4) {
                    var updateWarn = document.getElementById("istwislive");
                    updateWarn.innerHTML="TWIS will be live any time now. Refreshing the page when live.";
                    var checkLive=self.setInterval(function(){rechecklive();},30000);
                    function rechecklive() {
                        for(var i=0; i<feed.length; i++) {if(feed[i]['yt$status']['$t'] == 'active') {location.reload();}}
                    }
                }

It's saying that feed is not defined, but it's defined above at line 100. Anyone able to give me a help with this, or am I trying the impossible.

Is This A Good Question/Topic? 0
  • +

Replies To: Variable not available in children

#2 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3524
  • View blog
  • Posts: 10,169
  • Joined: 08-June 10

Re: Variable not available in children

Posted 05 September 2013 - 05:21 AM

Quote

It's saying that feed is not defined, but it's defined above at line 100.

and shadowed on line #105 and on line #106 you test, whether feed exist and if it does not (or at least if it is falsy) you try to use it in the inner function. (given its usage it should be an Array or NodeList and either of that would not trigger the else{} even if empty)
Was This Post Helpful? 0
  • +
  • -

#3 Arenlor  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 34
  • View blog
  • Posts: 389
  • Joined: 26-April 06

Re: Variable not available in children

Posted 05 September 2013 - 05:40 AM

I don't quite follow. From what I see if feed exists then it runs an if/else (lines 115 and 141). In the else section is where I'm trying to run this. The code I'm modifying is not my own, and I really am not a Javascript person. So if(feed) {if(event...){...}else{my if section on the current time/date}} which should allow me to have feed, unless I'm missing something.
Was This Post Helpful? 0
  • +
  • -

#4 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3524
  • View blog
  • Posts: 10,169
  • Joined: 08-June 10

Re: Variable not available in children

Posted 05 September 2013 - 06:09 AM

Quote

In the else section is where I'm trying to run this.

but the else section only runs if feed does not exist! (I mean, thatís the whole point of the if/else there).

How can you use a variable that you know does not exist?
Was This Post Helpful? 1
  • +
  • -

#5 Arenlor  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 34
  • View blog
  • Posts: 389
  • Joined: 26-April 06

Re: Variable not available in children

Posted 05 September 2013 - 07:50 AM

I thought that the else section ran if event doesn't exist, not if feed doesn't exist. I was not seeing the one closing squirrely bracket. Now I'll have to write it a different way, see if I can get it to work.
Was This Post Helpful? 0
  • +
  • -

#6 laytonsdad  Icon User is offline

  • Cheese and Sprinkles
  • member icon

Reputation: 436
  • View blog
  • Posts: 1,848
  • Joined: 30-April 10

Re: Variable not available in children

Posted 05 September 2013 - 08:43 AM

I see that in your else statement you are creating a variable called checkLive which is never used.
Was This Post Helpful? 0
  • +
  • -

#7 Arenlor  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 34
  • View blog
  • Posts: 389
  • Joined: 26-April 06

Re: Variable not available in children

Posted 05 September 2013 - 11:34 AM

The only example of setInterval I've seen had it like that. Any tips on it would be great. I normally do PHP and C with a touch of Java. I'm very procedural, no classes/functions for me if I can help it. Headers sure. I am working on that issue though.
For anyone curious, the following appears to be working:
                var curTime = new Date();
                if((curTime.getUTCHours() >=2 && curTime.getUTCHours() <=6) && curTime.getUTCDay() == 5) {
                    var updateWarn = document.getElementById("istwislive");
                    updateWarn.innerHTML="TWIS will be live any time now. Refreshing the page when live.";
                    var checkLive=self.setInterval(function(){rechecklive();},30000);
                    function rechecklive() {
                        HOAPlayer.prototype.fetchUserFeed(uid, 0, function(feed) {
                            if(feed){for(var i=0; i<feed.length; i++) {if(feed[i]['yt$status']['$t'] == 'active') {location.reload();}}}
                        });
                    }
                }

This is a beta1 version of it. Next week I'll make it prettier and better. Just trying to get it to work for now.
Was This Post Helpful? 1
  • +
  • -

#8 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3524
  • View blog
  • Posts: 10,169
  • Joined: 08-June 10

Re: Variable not available in children

Posted 05 September 2013 - 12:34 PM

are you sure the callback on line #7 is correct?
// post #7, line #5
...fetchUserFeed(uid, 0, function(feed) {
// post #1, line #100
...fetchUserFeed(uid, 0, function(err, feed) {


and another small one:
var checkLive=self.setInterval(function(){rechecklive();},30000);
// =>
window.setInterval(rechecklive, 30000);

Was This Post Helpful? 1
  • +
  • -

#9 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3524
  • View blog
  • Posts: 10,169
  • Joined: 08-June 10

Re: Variable not available in children

Posted 05 September 2013 - 12:42 PM

and while Iím at it
// for IE, requires version 9+ or a shim
function rechecklive() {
    HOAPlayer.prototype.fetchUserFeed(uid, 0, function(err, feed) { // assuming original parameters
        // assuming feed to be an Array
        if (feed.some(function(item) {
                return (item['yt$status']['$t'] == 'active');
            }) {
            location.reload();
        }
    });
}

Was This Post Helpful? 0
  • +
  • -

#10 Arenlor  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 34
  • View blog
  • Posts: 389
  • Joined: 26-April 06

Re: Variable not available in children

Posted 05 September 2013 - 01:42 PM

As far as I can tell the original developers didn't use the err at all neither. I'm not sure what feed is, could be an array. Mainly just trying to get this to work, even if it's not pretty. Thanks for the tip about setInterval
Was This Post Helpful? 0
  • +
  • -

#11 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3524
  • View blog
  • Posts: 10,169
  • Joined: 08-June 10

Re: Variable not available in children

Posted 05 September 2013 - 01:48 PM

View PostArenlor, on 05 September 2013 - 10:42 PM, said:

As far as I can tell the original developers didn't use the err at all neither.

that doesnít matter. since it is a callback function, the parameters are passed in by the system and the system doesnít care what name you give to the parameters. (admittedly, you can make a difference between callbacks that use a different amount of parameters, but that is always mentioned in the API docs)

and just because the original developers didnít use it doesnít mean their code doesnít use it.

for example Array.some(callback). callback() always receives 3 parameters, whether you use them or not doesnít concern Array.some() the least.
Was This Post Helpful? 0
  • +
  • -

#12 Arenlor  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 34
  • View blog
  • Posts: 389
  • Joined: 26-April 06

Re: Variable not available in children

Posted 05 September 2013 - 02:22 PM

I'm assuming not setting it can cause an issue somehow, so I've added it, but the chain seems to be from the call -> 197, which then uses it at 206 to call 233. Is err and feed being set at 240 to NULL and payload? If so, where is payload from?
Was This Post Helpful? 0
  • +
  • -

#13 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3524
  • View blog
  • Posts: 10,169
  • Joined: 08-June 10

Re: Variable not available in children

Posted 05 September 2013 - 03:48 PM

on line #195 you get the definition of the callback function:
// @param callback {Function(e, feed)} callback to be called


and on line #234 the explanation why he set NULL and payload:
// Here, I would like to do some error checking but not required


and on line #235 you see where payload comes from:
// this is a global function statement
   window[magic] = function(payload)
/* ============= */


and this function in turn looks like it is requested some lines above (#211 - #230) in a JSONP call.

This post has been edited by Dormilich: 05 September 2013 - 03:49 PM

Was This Post Helpful? 1
  • +
  • -

Page 1 of 1