Understanding the JavaScript delete operator

That’s this:

    function combineSettings(oldSettings, newSettings) {
        const props = Object.keys(oldSettings);
        return props.reduce(function combine(combined, prop) {
            if (oldSettings[prop].toString() === "[object Object]") {
                const oldProp = oldSettings[prop] || {};
                const newProp = newSettings[prop] || {};
                combined[prop] = combineSettings(oldProp, newProp);
            } else if (newSettings.hasOwnProperty(prop)) {
                combined[prop] = newSettings[prop];
            }
            return combined;
        }, oldSettings);
    }

But, you don’t need any of that delete stuff, or the combineSettings stuff. You can just put everything into one object, and give the youtube player that information as both its settings and its playerVars.

The youtube api just pays attention to what it needs to know, ignoring all the other stuff.

opts.playerVars = opts;
videoPlayer.init(opts.video, opts);

What are your thoughts on adding this to it?

["start", "end", "loop"].forEach(function (a) {
    if (settings[a]) {
        defaultSettings.playerVars[a] = settings[a];
    }
});

Full Code:


    function combineSettings(oldSettings, newSettings) {
        const props = Object.keys(oldSettings);
        return props.reduce(function combine(combined, prop) {
            if (oldSettings[prop].toString() === "[object Object]") {
                const oldProp = oldSettings[prop] || {};
                const newProp = newSettings[prop] || {};
                combined[prop] = combineSettings(oldProp, newProp);
            } else if (newSettings.hasOwnProperty(prop)) {
                combined[prop] = newSettings[prop];
            }
            return combined;
        }, oldSettings);
    }

    function addVideo(video, settings) {
        const defaultSettings = {
            width: settings.width || 640,
            height: settings.height || 390,
            videoId: video.dataset.id,
            playerVars: {
                autoplay: 1,
                controls: 1,
                showinfo: 1,
                rel: 0,
                iv_load_policy: 3,
                cc_load_policy: 0,
                fs: 0,
                disablekb: 1
            },
            events: {
                "onReady": onPlayerReady,
                "onStateChange": onPlayerStateChange
            }
        };
        ["start", "end", "loop"].forEach((a) => settings[a] && (defaultSettings.playerVars[a] = settings[a]));
        const updatedSettings = combineSettings(defaultSettings, settings);
        console.log(JSON.parse(JSON.stringify(updatedSettings)));
        players.push(new YT.Player(video, updatedSettings));
    }

    function init(video, settings) {
        load.js("https://www.youtube.com/player_api").then(function() {
            YT.ready(function() {
                addVideo(video, settings);
            });
        });
    }
    return {
        init
    };
}());

function loadPlayer(opts) {
    "use strict";
    const show = (el) => el.classList.remove("hide");

    function initPlayer(wrapper) {
        const video = wrapper.querySelector(".video");
        // default to 198x198 for multiple video players
        opts.width = opts.width || 198;
        opts.height = opts.height || 198;
        opts.playerVars = opts.playerVars || opts;
        videoPlayer.init(video, opts);
    }

    function coverClickHandler(evt) {
        const wrapper = evt.currentTarget.nextElementSibling;
        show(wrapper);
        initPlayer(wrapper);
    }
    const cover = document.querySelector(opts.target);
    cover.addEventListener("click", coverClickHandler);
}

That only works when start/end/loop are used.

What happens when you want to use any of the other 19 supported playerVars parameters?

1 Like

This is the fixed one:

.forEach

        ["start", "end", "loop"].forEach(function(a) {
            if (settings[a]) {
                defaultSettings.playerVars[a] = settings[a];
            }
        });

These use for loop:

        for (let a of ["start", "end", "loop"]) {
            if (settings[a]) defaultSettings.playerVars[a] = settings[a];
        }

https://jsfiddle.net/hzyrfkwb/566/

        const optional = ["start", "end", "loop"];
        for (let i = 0; i < optional.length; i++) {
            if (settings[optional[i]]) {
                defaultSettings.playerVars[optional[i]] = settings[optional[i]];
            }
        }

So it doesn’t need to be added to the default settings:
And also the loadPlayer.
It removes that duplication.

playerVars: {
                autoplay: 1,
                controls: 1,
                showinfo: 1,
                rel: 0,
                iv_load_policy: 3,
                cc_load_policy: 0,
                fs: 0,
                disablekb: 1
            },

I would have these:
These would get added to any of the players I wanted to add them to.
["start", "end", "loop"]

And then there would be the default ones:
These would get added to all of them

playerVars: {
                autoplay: 1,
                controls: 1,
                showinfo: 1,
                rel: 0,
                iv_load_policy: 3,
                cc_load_policy: 0,
                fs: 0,
                disablekb: 1
            },

You don’t need those default values. The youtube api already knows about all of those.

Which values are you referring to?

These?
"start", "end", "loop"

With your code these would’ve been needed to add to the default settings if they were ever used.

playerVars: {
                autoplay: 1,
                controls: 1,
                showinfo: 1,
                rel: 0,
                iv_load_policy: 3,
                cc_load_policy: 0,
                fs: 0,
                disablekb: 1
            },

If they are in here:

.forEach

        ["start", "end", "loop"].forEach(function(a) {
            if (settings[a]) {
                defaultSettings.playerVars[a] = settings[a];
            }
        });

They don’t need to be specified in the default settings:

You don’t need to restrict anything, because the youtube api just ignores anything that it doesn’t know about.

In your code:

These values won’t work unless they are specified in the default settings.

    start: 200,
    end: 205,
    loop: true

Using this, allows those values to work without being specified in the default settings.

        ["start", "end", "loop"].forEach(function(a) {
            if (settings[a]) {
                defaultSettings.playerVars[a] = settings[a];
            }
        });

default settings:

            playerVars: {
                autoplay: 1,
                controls: 1,
                showinfo: 1,
                rel: 0,
                iv_load_policy: 3,
                cc_load_policy: 0,
                fs: 0,
                disablekb: 1
            },

The multiple videos don’t seem to work after you did that.

They are working for me:

So these don’t need to be in the default settings.

loop: false,
start: 0,
end: 999999

I could just use this instead:

        ["start", "end", "loop"].forEach(function(a) {
            if (settings[a]) {
                defaultSettings.playerVars[a] = settings[a];
            }
        });

I’m going back to https://jsfiddle.net/89zwf62y/19/

Delete combineSettings and most of addVIdeo, and it all still works.

    function addVideo(video, settings) {
        settings.videoId = video.dataset.id;
        settings.playerVars = settings;
        players.push(new YT.Player(video, settings));
    }

and after that, initPlayer doesn’t need anymore than the following too:

    function initPlayer(wrapper) {
        const video = wrapper.querySelector(".video");
        opts.width = opts.width || 198;
        opts.height = opts.height || 198;
        videoPlayer.init(video, opts);
    }

You removed all the default settings, how come?

Because it’s not needed and it all still works.

How would I add these to it?

            playerVars: {
                autoplay: 1,
                controls: 1,
                showinfo: 1,
                rel: 0,
                iv_load_policy: 3,
                cc_load_policy: 0,
                fs: 0,
                disablekb: 1
            },

Any of the default values are not needed and don’t help the videoplayers to work any better than they did before.

1 Like

Auto play is needed, controls: , is needed,

I had default ones set .

However, if you’re desperate to add them in then it’s real easy.

Just replace this line:

settings.playerVars = settings;

with:

settings.playerVars = Object.assign({
    autoplay: 1,
    controls: 1
}, settings);
1 Like

This part isn’t working now:

This isn’t working either:
player.setVolume(0); // percent

    function onPlayerStateChange(event) {
        const player = event.target;
        if (event.data === YT.PlayerState.PLAYING) {
            const otherVideos = (video) => video !== player;
            const pauseVideo = (video) => video.pauseVideo();
            players.filter(otherVideos).forEach(pauseVideo);