0

I am trying to create a AngularJS widget (with AngularJS custom directive) through which user will able to use the widget as branch-locator on google map. Eg:

<branch-locator id="someId" branch-info="JSON-ARRAY"></branch-locator>

Where the JSON array will be like:

[
 {
   city : 'Los Angeles',
   desc : 'This city is amazing.',
   lat : 34.0500,
   long : -118.2500
 },
 {
   city : 'Chicago',
   desc : 'This is the second best city in the world!',
   lat : 41.8819,
   long : -87.6278
  }
]

But I want this data not to be hard-coded, rather I want to pass this data dynamically through jQuery. My Intention is that the end user must not care about internal semantics of AngularJS; The only requirement to use this widget is availability of data.

Now, my problem is that passing data to the directive, results in string like:

 [Object object, Object object]

Which is only string-array whose 0th index element is '[' not as expected:-

{
   city : 'Los Angeles',
   desc : 'This city is amazing..',
   lat : 34.0500,
   long : -118.2500
}

Following is the code snippet:

branchLocatorWidget.html

<script>
    $(function(){
         var cities = [
                          {
                              city : 'Toronto',
                              desc : 'This is the best city in the world!',
                              address : '',
                              lat : 43.7000,
                              long : -79.4000,
                          },
                          {
                              city : 'New York',
                              desc : 'This city is aiiiiite!',
                              address : '',
                              lat : 40.6700,
                              long : -73.9400
                          },
                          {
                              city : 'Chicago',
                              desc : 'This is the second best city in the world!',
                              address : '',
                              lat : 41.8819,
                              long : -87.6278
                          },
                          {
                              city : 'Los Angeles',
                              desc : 'This city is live!',
                              address : '',
                              lat : 34.0500,
                              long : -118.2500
                          },
                          {
                              city : 'Las Vegas',
                              desc : 'Sin City...\'nuff said!',
                              address : '',
                              lat : 36.0800,
                              long : -115.1522
                          }
                  ];


        $("branch-locator#someId").attr("branch-info",cities);

    });
</script>
<div>
    <branch-locator id="someId" branch-info=""></branch-locator>

</div>

BranchLocatorDirective.js

var uniqueId = 1;
var modified_id = "mapId";
define(["app"], function(app) {
    var modulename = 'branchLocator';

    angular.module("branchLocator", []).directive('branchLocator', function() {
        return {
            restrict: 'E',
            replace: true,
            scope: {
                branchInfo : "@",
                id : "@"
            },
            link: linkFunction,
            templateUrl: 'js/widget/directives/branchLocator/template/' + modulename + 'Template.html',
        };
    });

    var linkFunction = function(scope, element, attrs){
        var cities = eval(scope.branchInfo);
        console.log("From Directive: "+cities);
        console.log("Array Property: "+cities[0].city);
        console.log("Array Length: "+cities.length);
        scope.uniqueId = '_'+uniqueId++;
        modified_id = modified_id + scope.uniqueId;
        modified_id = element.find('div').attr('id' , modified_id).attr("id");
        plotMap(modified_id, cities, scope);
    }

    var plotMap = function(modified_id, cities, scope){
        // logic to plot locations on the google map
     }

});

branchLocatorTemplate.html

<div>
    <div id="mapId{{::uniqueId}}"></div>
</div>

However, if I try to pass the same literal through the controller on the scope property, it works fine, but my requirement is to refrain the directive from any dependency.

5
  • 4
    Why are you passing an object to Angular using jQuery? Why not just use Angular and get rid of jQuery completely? Commented Jun 10, 2016 at 9:35
  • Why don't you put your data in json file and read it form angular get call.. it works dynamically.. It would be great if you create jsfiddle for this Commented Jun 10, 2016 at 9:41
  • You are trying to mix 2 worlds together. Which could still be made to work. But the problem is, once you have an element in angular, you can bind it's attribute to scope data, you cannot just play with attributes directly. Commented Jun 10, 2016 at 10:34
  • @JeremyThille, Thanks for your suggestion, I am new to AngularJS, I am still learning it, I have no much idea, how to achieve the same behavior without using JQuery. A small code sample for the same will be very helpful to me Commented Jun 10, 2016 at 12:15
  • @PraveenMP , I want to make my widget generic, and leave this decision of using JSON file to the end user, who is going to use my widget. Commented Jun 10, 2016 at 12:16

1 Answer 1

1

Change

$("branch-locator#someId").attr("branch-info",cities);

To

angular.element("branch-locator#someId").scope().branchInfo = cities;

The idea is to use jqLite's angular.element() to fetch the object. jqLite is the light version of jQuery, if you already have jQuery included in your project, it defers to that automatically. Once you have the jqLite object pointing to your element, scope() method can hand you the scope of that so you can access it's properties. Definitely not the best way because you are combining the angular and jQuery worlds together. Avoid it if you can.

Also, a good developer will add some good checks.

var branchScope = angular.element("branch-locator#someId").scope();

if (typeof branchScope != "undefined") {
 branchScope.branchInfo = cities;
} else {
 throw "I could not find the scope of branch element";
}
Sign up to request clarification or add additional context in comments.

1 Comment

I am getting this following error on the console:- 'VM245:44 Uncaught ReferenceError: angular is not defined' I think, this is happening because JQuery is deferring jqLite, but I don't have choice other than to use JQuery, becuase my Widget is finally gonna integrate into JQuery environment only.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.