Generating an embedded object on the fly using an Angular Directive

After successfully establishing communication between the directive and controller, I am able to populate the embed code without any errors. However, the flash generated by the directive is not functioning at all, despite no visible discrepancies in the HTML structure compared to manually created embeds. Any insights or suggestions on why this might be happening would be greatly appreciated.

Below is a snapshot of how the site appears:

Here is the provided code snippet:

index.html

    <!DOCTYPE html>
    <html>
    <head>
        <link rel="stylesheet" href="dist/css/bootstrap.css"/>
        <link rel="stylesheet" href="dist/css/bootstrap-theme.css"/>
    </head>

    <body ng-app="App">
    <div ng-controller="MainCtrl">
        <div class="col-md-12">
            <h2>This is from the Controller and Directive</h2>
            Song[0] ID: {{Song[0].$id}}
            <flash-widget id="Song"></flash-widget>
        </div>
    </div>
    <div class="col-md-12">
        <h2>This is done Manually</h2>
        Song[0] ID: 4453334
        <object width="250" height="40">
            <embed src="http://grooveshark.com/songWidget.swf" type="application/x-shockwave-flash" width="250"height="40"flashvars="hostname=cowbell.grooveshark.com&amp;songIDs=4453334&amp;style=metal&amp;p=0" allowscriptaccess="always" wmode="window"/>
        </object>
    </div>
    </body>

    <script src="dist/js/angular.js"></script>
    <script src="js/tester.js"></script>
    </body>
    </html>

tester.js

    angular.module("App", [])
        .controller("MainCtrl", function($scope) {
            $scope.Song=[{
                    "AlbumName":"Unknown Album",
                    "ArtistName":"Angel City",
                    "SongName":"Love Me Right Feat. Laura McAllen[Rezonance Q Remix]",
                    "$id":"4453334",
                    "$priority":null
                },
                    {
                        "AlbumName":"Immersion",
                        "ArtistName":"Pendulum",
                        "SongName":"The Island - Part 1 - Dawn",
                        "$id":"26593443",
                        "$priority":null
                    },
                    {
                        "AlbumName":"Someone to Love Me",
                        "ArtistName":"Jomanda",
                        "SongName":"Got a Love for You",
                        "$id":"29376555",
                        "$priority":null
                    },
                    {
                        "AlbumName":"Avicii - Essential Mix (2010-12-11)",
                        "ArtistName":"Avicii",
                        "SongName":"Penguin",
                        "$id":"29533653",
                        "$priority":null
                    },
                    {
                        "AlbumName":"MOS Addicted To Bass 2011",
                        "ArtistName":"Eric Prydz",
                        "SongName":"Niton (The Reason)",
                        "$id":"30154682",
                        "$priority":null
                    }]
        })
        .directive('flashWidget', function(){
            return{
                restrict: 'E',
                scope: {id: '='},
                template: '<object width="250" height="40">'+
                '<embed src="http://grooveshark.com/songWidget.swf" type="application/x-shockwave-flash" width="250" height="40" flashvars="hostname=cowbell.grooveshark.com&songIDs={{id[0].$id}}&style=metal&p=0" allowscriptaccess="always" wmode="window"></embed>'+
                '</object>'
            }
        });

Answer №1

To assist you with your task, here is a plunker showcasing the desired functionality: http://plnkr.co/edit/t1UJMLtiBaKQnb7syPJH?p=preview

(function(){


angular.module("App", [])
        .controller("MainCtrl", function($scope) {
            $scope.Song=[{
                    "AlbumName":"Unknown Album",
                    "ArtistName":"Angel City",
                    "SongName":"Love Me Right Feat. Laura McAllen[Rezonance Q Remix]",
                    "$id":"4453334",
                    "$priority":null
                },
                    {
                        "AlbumName":"Immersion",
                        "ArtistName":"Pendulum",
                        "SongName":"The Island - Part 1 - Dawn",
                        "$id":"26593443",
                        "$priority":null
                    },
                    {
                        "AlbumName":"Someone to Love Me",
                        "ArtistName":"Jomanda",
                        "SongName":"Got a Love for You",
                        "$id":"29376555",
                        "$priority":null
                    },
                    {
                        "AlbumName":"Avicii - Essential Mix (2010-12-11)",
                        "ArtistName":"Avicii",
                        "SongName":"Penguin",
                        "$id":"29533653",
                        "$priority":null
                    },
                    {
                        "AlbumName":"MOS Addicted To Bass 2011",
                        "ArtistName":"Eric Prydz",
                        "SongName":"Niton (The Reason)",
                        "$id":"30154682",
                        "$priority":null
                    }];
            $scope.selectedSong = {}; 
            $scope.currentSong = function(){return $scope.selectedSong ; }
            $scope.selectSong = function (i){
                $scope.selectedSong = $scope.Song[i];
            };

        })
        .directive('flashWidget', function(){
            return{
                restrict: 'E',
                scope: {song: '&'},

                link: function(scope, elem, attrs) {

                    function updateDom(song){
                        if (song.$id == undefined)
                            return;
                        elem.html('<object width="250" height="40">'+
                        '<embed src="http://grooveshark.com/songWidget.swf" type="application/x-shockwave-flash" width="250" height="40" flashvars="hostname=cowbell.grooveshark.com&songIDs=' +
                        song.$id +
                        '&style=metal&p=0" allowscriptaccess="always" wmode="window"></embed>'+
                    '</object>');

                    }

                    scope.$watch(scope.song, function(value) {
                      updateDom(value)
                    });
                }
            }
        });

})()

Utilize the '&' operator to create a read-only connection between the controller and the directive. This operator establishes a binding between a directive scope property and an expression in the parent scope. In this scenario, the expression in the parent scope is a function that returns the current selected song. The selection of this song can occur through various methods, but in this case, it is triggered by a button click event.

Whenever the value of this expression changes (meaning when the current selected song changes), the $watch method associated with this directive property is activated, leading to the re-binding of the DOM element with the new song ID.

Answer №2

It is important to note that the {{id[0].$id}} in your template may not be evaluated immediately upon adding the element to the page. This can result in your flashvars receiving an invalid value. To ensure that you are passing the actual value and not just the unevaluated expression, consider creating the element within your link function once the desired value is known.

An example implementation could look like this:

.directive('flashWidget', function(){
    return{
        restrict: 'E',
        scope: {id: '='},
        link: function(scope, elem) {
            elem.append('<object width="250" height="40">'+
                '<embed src="http://grooveshark.com/songWidget.swf" type="application/x-shockwave-flash" width="250" height="40" flashvars="hostname=cowbell.grooveshark.com&songIDs=' +
                scope.id[0].$id +
                '&style=metal&p=0" allowscriptaccess="always" wmode="window"></embed>'+
            '</object>');
        }
    });
});

If your data can change dynamically, it might be necessary to wrap the creation of the element inside a scope.$watch.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Different placeholder text rendered in two text styles

Can an input box placeholder have two different styles? Here's the design I have in mind: https://i.stack.imgur.com/7OH9A.png ...

Tips for managing promise rejection when generating a highland stream from a promise?

When working with [email protected] and [email protected] via typescript, the following code snippet is utilized: import * as highland from "highland"; import * as lodash from "lodash/fp"; const range = lodash.range(0, 10); const createPromise ...

creating an HTML table from JSON data using a specific key

In this json file, I am looking to create separate tables based on the IDs provided. For example, ID: "50" should be displayed in one table, while ID: "57" should be shown in another table within the same context. { "version": "5.2", "user_type": ...

Retrieve the values of private variables within a defined function

While experimenting with typescript, I have encountered an issue that I can't seem to resolve. My project involves using Angular, so I will present my problem within that context. Here is a snippet of my code: class PersonCtrl{ private $scope: I ...

Displaying tooltips with ngx-charts in Angular

Currently, I am working on developing a unique legend component that features individual material progress bars for each data entry. My goal is to display the pie chart tooltip when hovering over any of the entries within this custom legend. Below is a sn ...

Image pop-ups that overlay text on the homepage

I'm facing an issue and I'm looking for a solution... Upon entering my homepage, I would like to display a popup image showcasing a new event so visitors can see it before accessing the website. I attempted to achieve this using JavaScript but w ...

Slider Troubles - Strange glitch when reaching final slide

Currently, I am in the process of developing a basic slider for a website. Although it is still a work in progress and both the script and styling are unfinished, I have encountered an issue. After clicking on the next button, I am able to cycle through al ...

What's the best way to add line numbers to source code on an HTML webpage after parsing?

I am currently working with AngularJS and MongoDB. In my MongoDB data, there are some text elements that contain a \n, causing each line to be displayed on a new line based on the occurrence of \n. However, I also want to add line numbers to each ...

React-redux: Data of the user is not being stored in redux post-login

Hello everyone, I am fairly new to using react-redux and I'm currently facing an issue with storing user information in the redux store after a user logs in. I am utilizing a django backend for this purpose. When I console out the user in app.js, it ...

Steps to expand all Bootstrap 5 accordions at once without collapsing any of the currently open ones

I own an accordion How can I expand all accordion items simultaneously by clicking on a single item? Consider the following scenario: Accordion Item #1 is open Accordion Item #2 is closed Accordion Item #3 is closed If we click on item #2 or #3, all ...

Implementing multiple conditions in ng-class for dynamic styling

Is there a way to make both && and || operators work in a single expression like the example below? ng-class = "{'class_name' : condition1 || condition2 || (condition3 && condition4)}" If it is possible, then how can it be implemented? ...

What is the best way to prevent double clicks when using an external onClick function and an internal Link simultaneously

Encountering an issue with nextjs 13, let me explain the situation: Within a card component, there is an external div containing an internal link to navigate to a single product page. Using onClick on the external div enables it to gain focus (necessary f ...

Building a game using Javascript and a database for a project

I am currently working on developing an online game using a combination of javascript and php. My main objective is to create a seamless, real-time gameplay experience without the need to constantly refresh the page. However, I have encountered a signific ...

Does ng-options function as intended in this scenario?

I need to set a default country in a select list and have it save the ID when a value is selected. $scope.countries = [ { id: 1, name: 'Italy' }, { id: 2, name: 'Spain' }, { id: 3, name: 'Germany' ...

What are the steps to configure Satellizer to utilize absolute URLs?

I'm currently in the process of creating a registration form using satellizer library, however, I am running into some issues with setting up the correct URL. Upon checking my console, I am seeing the following error message: POST http://localhost ...

"Pairing Angular's loader with RxJS combineLatest for seamless data

Hey there! Currently, I'm working on enhancing my Angular application by implementing a global loader feature. This loader should be displayed whenever data is being fetched from my API. To achieve this, I am utilizing ngrx actions such as fetchDataAc ...

Learn how to hide a bar after clicking the "I agree" button with the help of Bootstrap

click here to see imageIs there a way to make that bar disappear once the user clicks "I agree"? I've searched through Bootstrap documentation but couldn't find a solution. Please assist. Below is the code snippet: <div id="cookie-message" cl ...

Typeahead functionality in Angular UI Bootstrap that uses object properties to search and display

I have a similar item (recreation of Map): $scope.vehicles = { 1:{id:1, model:'Coupe'}, 2:{id:2, model:'Truck'}, 3:{id:3, model:'Hatchback'} } I want to utilize the property values in typeahead of ui bootstrap (whil ...

The error occurred in async JavaScript parallel code because the task is not recognized as a function

I am attempting to upload an image and update the image URL in the database collection using the code provided below. Controller.prototype.handle = function (req, res, next) { var id = req.params.id, controller = req.params.controller, optio ...

Ways to implement CSS on a parent element by manipulating its child element

Hello, I am looking to apply CSS to a parent element based on its child. <li> <div> <label> <b style="display: none;">Name and Date of Event*: </b> </label> </div> </li> ...