AngularJs - QueryString value & ng-include - angularjs

I am trying to capture the querystring and apply the value to my ng-include.
My querystring: http://mydomain.com/?target=W7ROP175T5TEHW2
My MainCtrl: $scope.target = $location.search()['target'];
$scope.target is picking up the value.
Doing a simple text write, ie {{target}} works.
This does not work: <div ng-include="'/_UserSession/{{target}}/assets/menu.html'"></div>
Any ideas?

You need to escape the value, it is an expression.
ng-include="'/_UserSession/' + target + '/assets/menu.html'"
Also if you want to make sure that target is set before it attempts to include the template, you can add ng-if ="target". This way it will avoid a bad request.

OK, I solved it, I hope this helps others as well:
HTML
<ng-include src="session()"></ng-include>
Controller
$scope.target = $location.search()['target'];
$scope.session = function() {
return "/_UserSession/" + $scope.target + "/assets/menu.html";
};

Related

Using $compile to compile a piece of HTML in AngularJS

In my controller,
I have a piece of code that outputs a string self.selectedProduct using template string expression..
This works as expected.
var productName = `
<div class='vertical-spacer'>|</div><div> ${self.selectedProduct}</div>`;
But when I want to add a directive that code breaks
var template = angular.element("<my-dropdown domainobject="domainobject"></my-dropdown>");
var linkFn = $compile(template)($scope);
productName = $(`
<div class='domain-wks-vertical-spacer'>|</div><div>`);
productName.append(linkFn);
So instead of the ${self.selectedProduct} I want to show the directive.
But I am not able to.
What am I doing wrong?
You are breaking the string using double quotes (") inside another double quote.
Try this:
var template = angular.element('<my-dropdown domainobject="domainobject"></my-dropdown>');

AngularJS custom directive does not work with in Handlebars template

This is the code that works:
<select-city country="US"></select-city>
This is the code that not works:
<select-city country="\{{country}}"></select-city>
For testing, I made this:
\{{country}}
It correctly prints US.
Note: I have to use \ because I use Handlebars template.
You need to change this line:
<select-city country="\{{country}}"></select-city>
To the following:
<select-city country="'\' + {{country}}"></select-city>
If you need to do this several times, it may be interesting to write a custom getter in order to avoid doing this in the view:
$scope.getCountry = function() {
return '\\' + $scope.country;
}
In the view:
<select-city country="{{getCountry()}}"></select-city>

AngularJS Directive to modify URL

In my templates i am able to display an image from my data using
ng-style="{'background-image':'url({{f.flower.imageURL}})'}"
The imageURL always returns a hi-res image with URL such as
https://s3.amazonaws.com/images/FlowerImages/Rose_1920.jpg
However the endpoint also has smaller images such as
https://s3.amazonaws.com/images/FlowerImages/Rose_320.jpg
https://s3.amazonaws.com/images/FlowerImages/Rose_480.jpg
https://s3.amazonaws.com/images/FlowerImages/Rose_1024.jpg
How would i create a directive to traverse back through the URL up to the underscore and pass in a size i want (depending on the view) to update between the underscore and the .jpg?
Based on you example, I don't think you need a directive. Just add a function to your controller.
Instead of
ng-style="{'background-image':'url({{f.flower.imageURL}})'}"
do
ng-style="{'background-image':'url({{generateImageUrl(f.flower.imageURL, 320)}})'}"
And your controller would have standard javascript to manipulate the url:
function generateImageUrl(url, size) {
var n = url.lastIndexOf("_");
var beforeUnderscore = url.substring(0, n);
var afterUnderscore = url.substring(n+1);
var suffix = afterUnderscore.split('.')[1];
return beforeUnderscore + "_" + size + "." + suffix;
}
The same function could work for image as well
<img ng-src="{{generateImageUrl(f.flower.imageURL, 320)}}">
Note: ng-src is used instead of src to prevent the browser from requested the url before angular has bootstrapped.

AngularJS Accessing Value In Querystring

Im trying to accessing a value in a querystring.
Here's what i see in the browser:
http://localhost:1010/products/chairs.html?searchMe=testing123
And in my Controller, i have:
var mySearchMeQuery = $location.search().searchMe;
console.log("searchMe = " + mySearchMeQuery );
In my console.log, i am seeing: searchMe = undefined
I have checked i have $location injected in my controller.
** Solution must work in IE8+ **
$location works only if you use path with hash (#). See this.
Use $location.search()
It returns an object key-value pairs; The key is your query string and the value is the query string value.
Example:
function MainCtrl($scope, $location) {
$scope.queryString = $location.search();
// returns {searchMe: "testing123"}
}
And if you want to print the same message as in your question
console.log("searchMe = " + $location.search().searchMe);
You can inject dependecy $routeParams and get the parameter value using something like this:
$routeParams.searchMe
Docs on routeParams
UPDATED Answer:
I have updated an existing fiddle which had $routeParams as an example. If you click on Moby link and check console over there you can see that SearchMe as a querystring is available.
Fiddle

How to use Backbone.Marionette.ItemView with Mustache

The following code works fine using Backbone.Marionette.ItemView but not Mustache.
Backbone.Marionette.ItemView - no Mustache
I would like to use the same code but loading the template varaible using Mustache.
Here is my code:
Backbone.Marionette.ItemView - with Mustache
Any idea why my code does not work and why?
Thanks
I'd like to update the answer here a bit as I was just struggling with this, and I was using this answer as a reference.
Here are my findings:
The answer here is a bit out of date with the current version of Mustache (which is understandable as it's pretty old)
Mustache.to_html is now deprecated, but still exists as a simple wrapper around Mustache.render for backwards compat. Check out this link.
Additionally, I found overriding Marionette.Renderer.render, as in the accepted answer above, completely bypasses the Marionette.TemplateCache layer which may not be the desired behavior.
Here's the source for the Marionette.Renderer.render method:
render: function(template, data){
if (!template) {
var error = new Error("Cannot render the template since it's false, null or undefined.");
error.name = "TemplateNotFoundError";
throw error;
}
var templateFunc;
if (typeof template === "function"){
templateFunc = template;
} else {
templateFunc = Marionette.TemplateCache.get(template);
}
return templateFunc(data);
}
Source
As you can see it accesses the Marionette.TemplateCache.get method and the above answer does nothing to maintain that functionality.
Now to get to my solve (note: the above answer is not wrong necessarily; this is just my approach to maintain the Marionette.TemplateCache layer):
As the comments suggest above, override compileTemplate instead:
Marionette.TemplateCache.prototype.compileTemplate = function(rawTemplate) {
// Mustache.parse will not return anything useful (returns an array)
// The render function from Marionette.Renderer.render expects a function
// so instead pass a partial of Mustache.render
// with rawTemplate as the initial parameter.
// Additionally Mustache.compile no longer exists so we must use parse.
Mustache.parse(rawTemplate);
return _.partial(Mustache.render, rawTemplate);
};
Here's a working JSFiddle as proof.
In the fiddle, I've also overridden Marionette.TemplateCache.loadTemplate to demonstrate that it's only called once. The body of the function only adds some debug output and then re-implements most of the original functionality (minus error handling).
Marionette assumes the use of UnderscoreJS templates by default. Simply replacing the template configuration for a view isn't enough. You also need to replace how the rendering process works.
In your simple example, you only need to override the Marionette.Renderer.render function to call Mustache, and then set the template of your views to the string template that you want:
Backbone.Marionette.Renderer.render = function(template, data){
return Mustache.to_html(template, data);
}
var rowTemplate = '{{ username }}{{ fullname }}';
// A Grid Row
var GridRow = Backbone.Marionette.ItemView.extend({
template: rowTemplate,
tagName: "tr"
});
Note that your JSFiddle still won't work even when you put this code in place, because the GridView is still using a jQuery selector/string as the template attribute. You'll need to replace this with the same type of template function to return mustache.
http://jsfiddle.net/derickbailey/d7qDz/

Resources