Render jade template with parameters that are angular binded upon render - angularjs

Upon request I render a jade template passing some parameters to template
res.render("result.jade",{order_id: "abc123"});
What is the best way to bind this passed parameters to scope variables when being rendered on client side? I haven't found any good solution except to render it to some hidden dom element and then take its text value (with jquery, for example) and assign it to scope variable, like this
// jade template
div.hidden #{order_id}
// javascript code
$scope.order_id = $(".hidden").text();

I would recommend you make this data available as a separate API call, such as REST. Then your Angular app would call this API to get the data on load, etc.

Related

How can an Angular directive have a 'native' parent state when it is compiled elsewhere?

I use ui-router to create routes with multiple HTML pages.
I have custom "target" directives within these pages that use $state.current in various ways.
But I also have other custom "lookup" directives in other states which load these HTML "templates", find these "target" directives, compile them and insert them into the DOM.
The problem I am having is that when the HTML content is compiled in these second directives, $state.current obviously refers to whatever state the application is in when it is compiled, whereas I would like the directive to compile as if it was in its "native" state.
Is there any (easy-ish!) way to get a reference to the target directive's "native" state? i.e. the state connected to the .HTML file which the directive is in? Is there a method (angular, jquery, native js or anything else) to get from the directive to the HTML template file? Then I could do a reverse lookup on the state objects. element.ownerDocument can get the URL of the current state, but not the HTML file of the template.
Alternatively, if the second directive had a reference to the "target" state, how should I modify the "target" directive so that it takes a state reference when it is compiled in both scenarios? Something in the compile function perhaps?? - but the docs don't seem to cover this kind of use case... I could do with a pointer in the right direction.
I hope that all makes sense. I have looked around for similar answers, but I guess this is an unusual use case? I'll knock up a Plunker shortly to help illustrate...
When you compile HTML using $compile, you pass in a scope object. Instead of using $state.current within the directive, could you attach the "state" you need to the scope object that you're passing in?

Right way to tell all directives that data has already loaded

I have SPA and on the first page I load a big data object from the REST service.
The first page consists of the main part which resolved by controller, set of directives in the current scope which render some parts of received object and a header directive in the $rootscope which also render some part of received data.
I call API in the controller and when all data will be loaded I should notify about it all related directives for rendering loaded data.
Now I use $watch() and $watchGroup() for the same scope directives and $rootScope.$broadcast() for the header from the $rootscope.
Is there any more gracefully solution for it?
What is the best way to do this?
This sounds like a good use case for ngResource, which is an official Angular module for REST resources. I'd recommend you create a service for your resource like:
app.factory('Widget', function ($resource) {
return $resource('/api/v1/widgets/:id');
});
Then you can use it in your controller to handle the loading of your data.
app.controller('WidgetController', function ($scope, Widget) {
$scope.widgets = Widget.query({active: true});
});
In your views/templates/whatever, can bind right to widgets, which will be an array of widgets that match the query. The array will be empty while the widgets load, then it will be populated with the results -- and the binding will automatically update.
You can also bind to widgets.$resolved which (essentially) indicates whether the resource has finished loading or not.
Check out more about ngResource here.

Bind an externally loaded DOM element to Angular's scope

I'm using Google Maps within an Angular app. As per Google Maps's API, I pass a string to a google.maps function containing HTML, and the library displays it on the map as an InfoView.
I'm adding a button to this view, and I want this view to be bound to a controller in my Angular app, however, even if I pass <div ng-controller="MyController">...</div>, when the Maps library attaches it to the DOM, Angular is not notified.
How can I force the compilation of this element (over which I have very little control: just passing a string)?
For AngularJS to "notice" the directive, it'd need to compile the element, which is not done automatically except when bootstrapping the application. So either the API needs to allow you to pass DOM Element to it (and you need to $compile and link it before you pass it on), or you need to find the element after it is added to DOM and then $compile and link it. AFAIK, if you cannot do either of those, then what you're asking is impossible.
If you manage to get hold of the element, compiling it is as simple as calling
$compile(element)($scope);
where $scope is the scope you want to link it to (possibly even $rootScope).

pass parameter to Angular directive template function post-post-link, using $scope, GET or whatever

I am trying to write a directive that will format content for modal display (using Bootstrap classes) if given a certain parameter, and as standard view if not. I have this working for a view loaded directly, toggling on a URL param (?modal) available to $routeParams and/or $location.
I want to use this toggle-able template as a "pipe" for other templates. However, the intended content URL will never be the visible URL when used as a modal. I can't get it working when loading the view with $modal.open or ngInclude, because $routeParams/$location has data for the including page, not the included one.
I put this in a Plunker, but because Plunker also doesn't provide the URL param, the modal view isn't available.
Does Angular provide a means to change the template or templateUrl much later in the process? For example, could I use $scope, either from a controller or on the directive, itself?
Clarification: The goal here is to have one template/partial for each component, with that template used either as a standalone or a modal, based on some switch. The _modal and _alone partials in the Plunker convert the component template into the desired state.
$modal.open takes a single object parameter one of the properties of this config parameter is templateUrl
http://angular-ui.github.io/bootstrap/
So you can create the config object and open the modal with any template you need.
Dan Wahlin uses this technique for a dialog service and then in this article goes on to demonstrate a full modal service
http://weblogs.asp.net/dwahlin/building-an-angularjs-modal-service
There were a couple of issues with your code:
First of all the use $routeParams if you don't use ngRoute's $routeProvider.
In your case, it might be easier to use $window.location.search (and compare it against ?modal).
That said, in order to properly display a Bootstrap modal, you need Bootstrap's JS file (which in turn requires jQuery) and you also need to create the modal (e.g. by calling $('.modal').modal()).
Take a look at this modified demo.
For better intergration with Angular's components, you might want to look into UI Bootstrap.

Call a normal JS function of other file after data from $http is loaded and is binded to the views

I want to call a regular JavaScript function after my webservice call has completed and all the data is binded to the respective views.
This JS function is in another file so I cannot access it in my Controller using $broadcast etc.
My webservice call gets data and fills it in an accordion, but the problem is the webservice is sometimes taking too long to return data; due to which the normal JS function is called prior to the completion of webservice call, the purpose of the normal JS function here is to provide expand functionality to the accordion li's which are filled from the webservice call, due to the above reason, the expand functionality is not binded to the li elements as they are generated after successful data return.
I do not want to use $delay or anything of that sort as I cannot say for sure how long it will take for the data to return.
What is the way to get around this, where and how can I call my normal JS function?
Can I defer the call of function in the directive itself or somewhere in the HTML file?
Wrap your 'normal JS function' using AngularJS 'service' / 'factory' / 'provider', you can then access it from anywhere using dependency injection of AngularJS.

Resources