Ludwig
Ludwig

Reputation: 1811

Angular ng-show and ng-hide and ng-if not working as expected

In my app, when I am doing ng-repeat for articles, on users click I want to hide and show some elements. For that I am using videoPlaying[$index], and it works fine for all the elements that have ng-hide, but for iframe that has ng-show it is not working as expected, in the chrome console, I can see that iframe gets ng-hide class when I click to play video. Video starts playing but it has the wrong class. I have tried with ng-if as well, and then hide and show works fine, but the video won't work, which is strange, because video works when I have ng-show, and with ng-if I get the console error:

Cannot read property 'playVideo' of undefined

Not sure how to fix that?

My html:

<div ng-if="slider.length == 0 && article.external_media.length == 1">
  <img ng-hide="videoPlaying" ng-src="http://i1.ytimg.com/vi/{{ article.external_media[0].video_id }}/maxresdefault.jpg" class="cover">
  <youtube-video ng-show="videoPlaying" video-url="article.external_media[0].original_url" player="youtubePlayer" player-vars="playerVars" class="video"></youtube-video>
  <div ng-hide="videoPlaying" class="iframe-overlay" ng-click="playVideo(youtubePlayer)">
    <img ng-hide="videoPlaying" ng-click="playVideo(youtubePlayer)" class="play" src="icons/play.svg"/>
    <img ng-hide="videoPlaying" ng-click="playVideo(youtubePlayer)" class="playButton" src="icons/playRectangle.svg"/>
  </div>
</div>

My controller:

$scope.videoPlaying = [];
  $scope.playerVars = {
    controls: 0,
    showinfo: 0
  };

  $scope.playVideo = function(youtubePlayer, index) {
    $scope.videoPlaying[index] = true;
    youtubePlayer.playVideo();
  };

Update

I have tried the Dinesh suggestion, and it works on the articles page, but when I have it on the article page, the same logic, it is not working for when I only have one video and I don't need a slider, but it is working when I have a slider, I have commented the parts that are working and not working in the html code, not sure why and how to tackle this issue?

When I have:

<youtube-video ng-show="videoPlaying" video-url="article.external_media[0].original_url" player="youtubePlayer" player-vars="playerVars" class="video"></youtube-video>

With that, after a click, I can see in console, that it has ng-hide class which it shouldn't have.

If I have it like this:

<youtube-video ng-show="!videoPlaying" video-url="article.external_media[0].original_url" player="youtubePlayer" player-vars="playerVars" class="video"></youtube-video>

Then it is behaving as expected and showing immediately below the image, which I don't want to.

And if I am using ng-if then it the elements are hidden and shown as they should be but the video is not starting as with ng-show, like it should!

<youtube-video ng-if="videoPlaying" video-url="article.external_media[0].original_url" player="youtubePlayer" player-vars="playerVars" class="video"></youtube-video>

This is the part of the article page (the one that is not working):

  <!-- this part is not working -->
  <img ng-hide="videoPlaying" ng-src="http://i1.ytimg.com/vi/{{ article.external_media[0].video_id }}/maxresdefault.jpg" class="cover">
  <youtube-video ng-show="videoPlaying" video-url="article.external_media[0].original_url" player="youtubePlayer" player-vars="playerVars" class="video"></youtube-video>
  <div ng-hide="videoPlaying" class="iframe-overlay" ng-click="playVideo(youtubePlayer)">
    <img ng-hide="videoPlaying" class="play" src="icons/play.svg"/>
    <img ng-hide="videoPlaying" class="playButton" src="icons/playRectangle.svg"/>
  </div>

    <!-- this part works -->
    <ion-slides ng-if="slider.length > 0" class="slides">
      <ion-slide-page ng-repeat="item in slider">
        <img ng-if="item.image" ng-src="{{ fileServer }}/imagecache/cover/{{ item.image }}" class="cover">
        <div class="iframe" ng-if="item.video">
          <img ng-hide="videoPlaying" ng-src="http://i1.ytimg.com/vi/{{ item.video.video_id }}/maxresdefault.jpg" class="cover">
          <youtube-video ng-show="!videoPlaying" video-url="article.external_media[0].original_url" player="youtubePlayer" player-vars="playerVars" class="video"></youtube-video>
          <div ng-hide="videoPlaying" class="iframe-overlay" ng-click="playVideo(youtubePlayer)">
            <img ng-hide="videoPlaying" ng-click="playVideo(youtubePlayer)" class="play" src="icons/play.svg"/>
            <img ng-hide="videoPlaying" ng-click="playVideo(youtubePlayer)" class="playButton" src="icons/playRectangle.svg"/>
          </div>
        </div>
      </ion-slide-page>
    </ion-slides>

My article controller:

$scope.videoPlaying = false;
  $scope.playerVars = {
    controls: 0,
    showinfo: 0
  };

  $scope.playVideo = function(youtubePlayer) {
    $scope.videoPlaying = true;
    youtubePlayer.playVideo();
  };

The articles page (where it works):

<div class="iframe" ng-show="article.external_media.length > 0 && article.external_media.url != ''">
            <img ng-hide="videoPlaying[$index]" class="img" ng-src="http://i1.ytimg.com/vi/{{ article.external_media[0].video_id }}/maxresdefault.jpg">
            <youtube-video ng-show="!videoPlaying[$index]" video-url="article.external_media[0].original_url" player="youtubePlayer" player-vars="playerVars" class="iframe-video"></youtube-video>
            <h1 ng-hide="videoPlaying[$index]">{{ article.title.split(' ', 7).join(' ') }}</h1>
            <div ng-hide="videoPlaying[$index]" class="iframe-overlay" ng-click="playVideo(youtubePlayer, $index)"></div>
            <img ng-hide="videoPlaying[$index]" ng-click="playVideo(youtubePlayer, $index)" class="play" src="icons/play.svg"/>
            <img ng-hide="videoPlaying[$index]" ng-click="playVideo(youtubePlayer, $index)" class="playButton" src="icons/playRectangle.svg"/>
          </div>

Controller:

$scope.videoPlaying = [];
  $scope.playerVars = {
    controls: 0,
    showinfo: 0
  };

  $scope.playVideo = function(youtubePlayer, index) {
    $scope.videoPlaying[index] = true;
    youtubePlayer.playVideo();
  };

Upvotes: 0

Views: 771

Answers (2)

Dinesh Shah
Dinesh Shah

Reputation: 1233

just do one thing.

replace

ng-show="videoPlaying[$index]" 

with

ng-show="!videoPlaying[$index]"

Upvotes: 1

Dan M. CISSOKHO
Dan M. CISSOKHO

Reputation: 1065

Try to replace it by a "ng-if", on the video element "ng-show" can be apply to the child element

Upvotes: 0

Related Questions