I'm trying to get my head around scopes and after dredging through a number of blogs, stack overflow answers and the docs I am still stuck.
angular.module('app', [])
.factory('alphabet', function () {
data = [
'c',
'b',
'a'
];
return {
get : function () {
return data;
},
set : function (val) {
data.push(val);
}
};
})
.controller('AlphaCtrl', function (alphabet) {
this.alphabet = alphabet;
})
.directive('sortableTable', function () {
return {
scope : {
"param" : '#'
},
link : function (scope) {
console.log(scope.param);
}
};
})
;
HTML:
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div ng-controller="AlphaCtrl as alpha">
<table sortable-table param="{{alpha.alphabet}}">
<thead>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</body>
</html>
What I would like to do is be able to access a service/factory that's being used in an outer controller from within a directive. So for example when I handle a click event I can add items to the data. That seems to be a good way of keeping things decoupled but I am open to suggestions there.
The problem at hand is that 'param' is undefined. I've also tried using '&' but that's not doing anything for me. Could someone put me on the path to Angular righteousness?
I would inject the service directly into the directive:
.directive('sortableTable', function (alphabet) {
return {
scope : {},
link : function (scope) {
console.log(alphabet);
}
};
})
This is indeed a good way of keeping things decoupled, if this is a directive that is used across controllers and views.
Edit for a bit more complex solution: It is possible to do it by injecting the service into the scope of the directive, though I would not recommend it if you don't need to switch services on the fly, since the method above is easier. I could see some use cases though, if you would want to input a different service (with the same get/set structure) in another controller for example. Here's how you could do it via scope:
.controller('myController', function($scope, alphabet) {
$scope.alphabet = alphabet;
})
.directive('myDirective', function(){
return {
scope: {
service: '='
},
template: '<div ng-bind="service.get()"></div>'
}
})
And in the template:
<div data-my-directive service="alphabet"></div>
The trick here is using service: '=' as this creates a two-way binding between the scope-variable in the controller (which is bound to the service) and the scope-variable in the directive. http://jsfiddle.net/vt52bauu/2/
I don't think the get/set is going to work the way you are expecting in an Angular factory.
this.alphabet = alphabet.get();
Related
I am new to AngularJS. I want to return template to directive with addition and subtraction of two numbers. I am passing $scope in function but it is not working.
I'm learning from Angular Modules with Directive
here is the code :
<html>
<head>
<title>Angular JS </title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
</head>
<body>
<div ng-app="Compl">
<input type=number ng-model="no1" placeholder="Enter the First Number" />
<input type=number ng-model="no2" placeholder="Enter the First Number" />
<NoSum></NoSum>
<NoSub></NoSub>
</div>
<script>
var app = angular.module("Compl", []);
app.directive("NoSum", function($scope) {
return {
template: "Sum of Two Number" + ($scope.no1 + $scope.no2)
};
});
app.directive("NoSub", function($scope) {
return {
template: "Sub of Two Number" + ($scope.no1 - $scope.no2)
};
});
</script>
</body>
</html>
If you're not using isolated scope, you should be able to just use no1 and no2 directly in the template. assuming those are variables in the parent scope.
<script>
var app = angular.module("Compl", []);
app.directive("noSum",function(){
return{
template : "Sum of Two Number {{(no1 + no2)}}"
};
});
app.directive("noSub",function(){
return{
template : "Sub of Two Number {{(no1 - no2)}}"
};
});
</script>
You should also rename your directives, since capitalized letters have special meaning in angular. So with my changed names above, your html should look like this:
<no-sum></no-sum>
<no-sub></no-sub>
Here is a Plunker showing it working as expected
This works because without isolated scope, your directives inherit the scope of their parent, which in your case is the $rootScope. If you used isolated scope instead, you would have to pass in the variables through html attributes.
What you can do is
a) use the 'parent scope' .. so te scope of the controller of the view which contains your directive and so like this:
app.directive("NoSum",function($scope){
return {
template: "Sum of Two Number" + (scope.no1 + scope.no2) //<-- don't use scope with $ ... but only scope
link: function(scope, element, attrs) {
element.bind('error', function() {
if (attrs.src !== attrs.errSrc) {
attrs.$set('src', attrs.errSrc);
}
});
}
};
});
2 - use 'isolated scope' .. so you force to pass the scope trought your item like so:
app.directive("noSum",function($scope){
return {
restrict:'EAC'
template: "Sum of Two Number" + (item.no1 + item.no2) //<-- here you use item and in html you use like: <no-sum item="myvarscoped"></no-sum>
scope:{ item : "="}
link: function(scope, element, attrs) {
element.bind('error', function() {
if (attrs.src !== attrs.errSrc) {
attrs.$set('src', attrs.errSrc);
}
});
}
};
});
As Vivz has already mentioned, you can't pass scopes. Best practice is to share data between controllers/directives is to use factories. See this link for particular example.
Is it possible to create an HTML fragment in an AngularJS controller and have this HTML shown in the view?
This comes from a requirement to turn an inconsistent JSON blob into a nested list of id: value pairs. Therefore the HTML is created in the controller and I am now looking to display it.
I have created a model property, but cannot render this in the view without it just printing the HTML.
Update
It appears that the problem arises from angular rendering the created HTML as a string within quotes. Will attempt to find a way around this.
Example controller :
var SomeController = function () {
this.customHtml = '<ul><li>render me please</li></ul>';
}
Example view :
<div ng:bind="customHtml"></div>
Gives :
<div>
"<ul><li>render me please</li></ul>"
</div>
For Angular 1.x, use ng-bind-html in the HTML:
<div ng-bind-html="thisCanBeusedInsideNgBindHtml"></div>
At this point you would get a attempting to use an unsafe value in a safe context error so you need to either use ngSanitize or $sce to resolve that.
$sce
Use $sce.trustAsHtml() in the controller to convert the html string.
$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml(someHtmlVar);
ngSanitize
There are 2 steps:
include the angular-sanitize.min.js resource, i.e.:
<script src="lib/angular/angular-sanitize.min.js"></script>
In a js file (controller or usually app.js), include ngSanitize, i.e.:
angular.module('myApp', ['myApp.filters', 'myApp.services',
'myApp.directives', 'ngSanitize'])
You can also create a filter like so:
var app = angular.module("demoApp", ['ngResource']);
app.filter("trust", ['$sce', function($sce) {
return function(htmlCode){
return $sce.trustAsHtml(htmlCode);
}
}]);
Then in the view
<div ng-bind-html="trusted_html_variable | trust"></div>
Note: This filter trusts any and all html passed to it, and could present an XSS vulnerability if variables with user input are passed to it.
Angular JS shows HTML within the tag
The solution provided in the above link worked for me, none of the options on this thread did. For anyone looking for the same thing with AngularJS version 1.2.9
Here's a copy:
Ok I found solution for this:
JS:
$scope.renderHtml = function(html_code)
{
return $sce.trustAsHtml(html_code);
};
HTML:
<p ng-bind-html="renderHtml(value.button)"></p>
EDIT:
Here's the set up:
JS file:
angular.module('MyModule').controller('MyController', ['$scope', '$http', '$sce',
function ($scope, $http, $sce) {
$scope.renderHtml = function (htmlCode) {
return $sce.trustAsHtml(htmlCode);
};
$scope.body = '<div style="width:200px; height:200px; border:1px solid blue;"></div>';
}]);
HTML file:
<div ng-controller="MyController">
<div ng-bind-html="renderHtml(body)"></div>
</div>
Fortunately, you don't need any fancy filters or unsafe methods to avoid that error message. This is the complete implementation to properly output HTML markup in a view in the intended and safe way.
The sanitize module must be included after Angular:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular-sanitize.js"></script>
Then, the module must be loaded:
angular.module('app', [
'ngSanitize'
]);
This will allow you to include markup in a string from a controller, directive, etc:
scope.message = "<strong>42</strong> is the <em>answer</em>.";
Finally, in a template, it must be output like so:
<p ng-bind-html="message"></p>
Which will produce the expected output: 42 is the answer.
I have tried today, the only way I found was this
<div ng-bind-html-unsafe="expression"></div>
ng-bind-html-unsafe no longer works.
This is the shortest way:
Create a filter:
myApp.filter('unsafe', function($sce) { return $sce.trustAsHtml; });
And in your view:
<div ng-bind-html="customHtml | unsafe"></div>
P.S. This method doesn't require you to include the ngSanitize module.
on html
<div ng-controller="myAppController as myCtrl">
<div ng-bind-html-unsafe="myCtrl.comment.msg"></div>
OR
<div ng-bind-html="myCtrl.comment.msg"></div
on controller
mySceApp.controller("myAppController", function myAppController( $sce) {
this.myCtrl.comment.msg = $sce.trustAsHtml(html);
works also with $scope.comment.msg = $sce.trustAsHtml(html);
I found that using ng-sanitize did not allow me to add ng-click in the html.
To solve this I added a directive. Like this:
app.directive('htmldiv', function($compile, $parse) {
return {
restrict: 'E',
link: function(scope, element, attr) {
scope.$watch(attr.content, function() {
element.html($parse(attr.content)(scope));
$compile(element.contents())(scope);
}, true);
}
}
});
And this is the HTML:
<htmldiv content="theContent"></htmldiv>
Good luck.
Just did this using ngBindHtml by following angular(v1.4) docs,
<div ng-bind-html="expression"></div>
and expression can be "<ul><li>render me please</li></ul>"
Make sure you include ngSanitize in the module's dependencies.
Then it should work fine.
Another solution, very similar to blrbr's except using a scoped attribute is:
angular.module('app')
.directive('renderHtml', ['$compile', function ($compile) {
return {
restrict: 'E',
scope: {
html: '='
},
link: function postLink(scope, element, attrs) {
function appendHtml() {
if(scope.html) {
var newElement = angular.element(scope.html);
$compile(newElement)(scope);
element.append(newElement);
}
}
scope.$watch(function() { return scope.html }, appendHtml);
}
};
}]);
And then
<render-html html="htmlAsString"></render-html>
Note you may replace element.append() with element.replaceWith()
there is one more solution for this problem using creating new attribute or directives in angular.
product-specs.html
<h4>Specs</h4>
<ul class="list-unstyled">
<li>
<strong>Shine</strong>
: {{product.shine}}</li>
<li>
<strong>Faces</strong>
: {{product.faces}}</li>
<li>
<strong>Rarity</strong>
: {{product.rarity}}</li>
<li>
<strong>Color</strong>
: {{product.color}}</li>
</ul>
app.js
(function() {
var app = angular.module('gemStore', []);
app.directive(" <div ng-show="tab.isSet(2)" product-specs>", function() {
return {
restrict: 'E',
templateUrl: "product-specs.html"
};
});
index.html
<div>
<product-specs> </product-specs>//it will load product-specs.html file here.
</div>
or
<div product-specs>//it will add product-specs.html file
or
<div ng-include="product-description.html"></div>
https://docs.angularjs.org/guide/directive
you can also use ng-include.
<div class="col-sm-9 TabContent_container" ng-include="template/custom.html">
</div>
you can use "ng-show" to show hide this template data.
here is the solution make a filter like this
.filter('trusted',
function($sce) {
return function(ss) {
return $sce.trustAsHtml(ss)
};
}
)
and apply this as a filter to the ng-bind-html like
<div ng-bind-html="code | trusted">
and thank to Ruben Decrop
Use
<div ng-bind-html="customHtml"></div>
and
angular.module('MyApp', ['ngSanitize']);
For that, you need to include angular-sanitize.js,
for example in your html-file with
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular-sanitize.js"></script>
Here's a simple (and unsafe) bind-as-html directive, without the need for ngSanitize:
myModule.directive('bindAsHtml', function () {
return {
link: function (scope, element, attributes) {
element.html(scope.$eval(attributes.bindAsHtml));
}
};
});
Note that this will open up for security issues, if binding untrusted content.
Use like so:
<div bind-as-html="someHtmlInScope"></div>
Working example with pipe to display html in template with Angular 4.
1.Crated Pipe escape-html.pipe.ts
`
import { Pipe, PipeTransform } from '#angular/core';
import { DomSanitizer } from '#angular/platform-browser';
#Pipe({name : 'keepHtml', pure : false})
export class EscapeHtmlPipe implements PipeTransform{
constructor(private sanitizer : DomSanitizer){
}
transform(content){
return this.sanitizer.bypassSecurityTrustHtml(content);
}
}
`
2. Register pipe to app.module.ts
import {EscapeHtmlPipe} from './components/pipes/escape-html.pipe';
declarations: [...,EscapeHtmlPipe]
Use in your template
<div class="demoPipe" [innerHtml]="getDivHtml(obj.header) | keepHtml">
getDivHtml() { //can return html as per requirement}
Please add appropriate implementation for getDivHtml in associated component.ts file.
Just simple use [innerHTML], like below:
<div [innerHTML]="htmlString"></div>
Before you needed to use ng-bind-html...
Basically I am trying to access controller scope property from directive's controller function. I am doing it through $parent property. It works fine for static directive but not for dynamically created directive.
please have a look on my plunker
Dynamic Directive
In a plunker, when I click on folder with Id = 1. all goes good and folder path shows as "1 path". Same goes for folder with Id = 2.
But it does not work for dynamically appended folder with Id = n
I am somewhat new to angular. Any help would be much appreciated.
Updated Answer
In light of the latest requirement:
I am trying to call the directive function (i.e updateMap) from
controller.
You can use a Service to share variables between Controllers and Isolated Directives. In the example below, the Service holds the function that will be executed. Each directive when clicked will set the Service's function to it's own updateMap() function. Then the Controller in onFolderPathClicked() calls the Services executeFunction() function, which runs the previously set function.
script.js:
var module = angular.module('testApp', []);
module.service('updateMapService', function(){
var updateMapFunction = null;
this.executeFunction = function(){
updateMapFunction();
};
this.setFunction = function(fn){
updateMapFunction = fn;
};
});
module.controller('crtl', function($scope, updateMapService) {
$scope.onFolderPathClicked = function(){
updateMapService.executeFunction();
};
});
module.directive('folder', function($compile) {
return {
restrict: 'E',
scope: {
id: '#',
folderPath: "="
},
template: '<p ng-click="onFolderClicked()">{{id}}</p>',
controller: function($scope, $element, updateMapService) {
$scope.onFolderClicked = function(){
updateMapService.setFunction(updateMap);
addFolder();
};
var addFolder = function() {
$scope.folderPath = $scope.id + ":click here for calling update map";
var el = $compile('<folder id="n" folder-path="folderPath"></folder>')($scope);
$element.parent().append(el);
};
var updateMap = function() {
alert('inside updateMap()..' + $scope.id);
}
}
}
});
index.html:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div ng-app="testApp" ng-controller="crtl">
<div>FolderPath : <a ng-click="onFolderPathClicked()">{{ folderPath }}</a> </div>
<folder id="1" folder-path="folderPath"></folder>
<folder id="2" folder-path="folderPath"></folder>
</div>
</html>
You could also move folder-path into a Service to save from passing it in as an attribute. The code smell being that passing it in as an attribute means doing so twice, whereas in a Service it means setting it and getting it once (code reuse).
I have some trouble identifying a view update that is not happening neither when I set a property on the $scope nor when I set a property on the controller prototype.
I have create a quick example of what I am doing to illustrate the issue.
I have, for instance the following view:
<html data-ng-app="test">
<head>
<script data-require="angular.js#1.2.18" data-semver="1.2.18" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<h1>Hello Plunker!</h1>
<div data-catalog="{ 'type': 'Category1', 'key': '252' }">
<span class="text-danger">{{query | json}}</span>
<span class="text-danger">{{catalog.model | json}}</span>
</div>
</body>
</html>
And a simple module with a directive and a controller:
angular
.module("test", [])
.controller("CatalogCtrl", ["$scope", "$parse", "$location", "$q", function ($scope, $parse, $location, $q) {
var catalog = this,
listener = function () {
var query = {},
params = $location.search();
try
{
query = $parse($scope.query)();
}
catch (exception)
{
console.error(exception);
}
if (_.isEmpty(query))
{
return;
}
$q
.all([
scroll({ top: 0 }),
Catalog.searchProducts(_.assign(query, params))
])
.then(function (response) {
catalog.model = response[1];
console.log(catalog.model, response[1]);
})
.catch(function () {
catalog.model = {};
})
.finally(function () {});
};
catalog.model = {test:""};
//$scope.listen("$locationChangeSuccess", listener);
}])
.directive("catalog", function () {
return {
controller: "CatalogCtrl as catalog",
scope: {
query: "#catalog"
},
restrict: "A",
replace: false
};
});
The issue is that neither {{query | json}} nor {{catalog.model | json}} are rendered in the view and I am not sure what is the cause of it. It might be something I am missing or doing wrong, but I could use some help with it if anyone spots my mistake :)
There are a few issues with your code...
1.
Your directive has it controlelr attached and you place some values on its scope (query, catalog etc). Then you try to access those values from an element that is outside of the directive (and thus has a different scope that knows nothing about query, catalog etc. E.g.
<!-- Let's say somehow DIV#1 has scope $001 -->
<div id="1">
<!-- Somehow DIV#1.1 creates a new scope ($002) -->
<div id="1.1" some-directive>
<!-- DIV#1.1.1 will have access to scope $002 -->
<!-- (under certain cirsumstances) -->
<div id="1.1.1"></div>
</div>
<!-- DIV#1.2 (which is outside of DIV#1.1) -->
<!-- will have access to scope $001 (but not $002) -->
<div id="1.2"></div>
</div>
2.
To make things even more complicated, your directive creates an isolate scope, which means that any content it has will not see your directive's scope, but its parent scope. I.e. in the example above, DIV#1.1.1 will have access to scope $001, not $002.
What you can do about it (which basically mean, explicitly state that your directive's content should be included (transcluded) into its template. This gives you greater control on what's going on and allows you to bind the content of your directive to the scope you want (i.e. your directive's isolate scope).
The resulting code should look like this:
<div data-pj-catalog="{ 'type': 'Category1', 'key': '252' }">
...
<div class="col-12">
...
<span class="text-danger">{{query | json}}</span>
<span class="text-danger">{{catalog.model | json}}</span>
...
<div>
</div>
.directive('pjCatalog', function () {
return {
restrict: 'A',
transclude: true,
template: '<div ng-transclude></div>',
controller: 'CatalogCtrl',
scope: {
query: '#pjCatalog'
},
link: function (scope, elem, attrs, ctrls, transFn) {
transFn(scope, function (cloned) {
elem.empty().append(cloned);
});
}
};
})
See, also, this short demo.
Note:
This is considered "advanced" directive stuff (so it sounds (and is) much more complicated than most directive stuff) and should be required in rae cases only.
I am pretty sure there is a much easier way to achieve what you want (e.g. using a non-isolate scope) with slight modifications (but I am not sure what you want in order to help further.
I have the below HTML on a page:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="myCart">
<head>
<title>AngularJS Shopping Cart</title>
<link href="css/jsonstore.css" rel="stylesheet" />
</head>
<body>
<div id="container">
<div id="header">
<h1>The JSON Store</h1>
<div class="cart-info">
My Cart (<span class="cart-items">{{item.basketCount}}</span> items)
</div>
</div>
<div id="main" ng-view>
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular-resource.js"></script>
<script src="js/routing.js"></script>
<script src="js/dataresource.js"></script>
<script src="js/basketinfo.js"></script>
<script src="js/index.js"></script>
<script src="js/detail.js"></script>
</body>
</html>
The div "main" gets replaced by HTML templates by my routes however I would like to update the header section with a shopping basket count.
I have tried model binding it as shown in the HTML and below:
function DetailController($scope, item, basketDetail) {
$scope.item = item;
$scope.item.basketCount = basketDetail.getCount();
//more code
}
I've also tried just injecting the service and calling it from the HTML. Both ways do not do anything.
Can someone help please?
Thanks
Your header div is really a view, just like the other views you've defined for use with ng-view. Someday, you might want to show more than just a basketCount model in that header view. But the fact that you are projecting even one piece of model data into that header section makes that section a view. So, I would recommend that be given its own $scope to project that model, hence its own controller.
What remains then is where to put the basketCount model? And we must consider that multiple views may allow the user to do something that need to affect that model. Angular's normal answer for "many need access" is dependency injection. So, I would put the basketCount model into a service. Views/controllers that need access to it can inject it. Someday your app may have additional views that don't need access to these models, so those views would not inject the service.
Potentially, the entire basket could be modeled in this service:
app.factory('basketService', function() {
return {
items: [],
itemCount: 0,
...
}
});
function HeaderCtrl($scope, basketService) {
$scope.basket = basketService;
...
}
function DetailCtrl($scope, basketService) {
$scope.basket = basketService;
...
}
<div id="header" ng-controller="HeaderCtrl">
<h1>The JSON Store</h1>
<div class="cart-info">
My Cart (<span class="cart-items">{{basket.itemCount}}</span> items)
</div>
You'll need to inject $rootScope, then update it:
function DetailController($scope, $rootScope, basketDetail) {
$rootScope.item = $rootScope.item || {};
$rootScope.item.basketCount = basketDetail.getCount();
//more code
}
There are a lot more ways to do this, but this is my first suggestion, because it's probably the easiest.
EDIT: per your request, other ways to do this...
You could use $parent to push to your parent scope. The upside is it's pretty quick and clean... the downside is it's a little sloppy in that one of your controllers makes assumptions about what it's parent is to some degree (but that's still not terrible, really):
{{item.basketCount}}
<div ng-controller="InnerCtrl">
</div>
function InnerCtrl($scope, basketDetail) {
$scope.$parent.item = $scope.$parent.item || {};
$scope.$parent.item.basketCount = basketDetail.getCount();
}
Then there's the method #asgoth mentioned above where you use nested controller and a method on the parent scope to update the parent scope. Valid, but like my other solution in this "other ways to do it" section, it relies on assumptions made about the controller's container, and it also relies on you creating an additional controller.
Finally, you could create a service. Now services aren't generally used this way, but you could use one this way.. Where you could take your basketDetail service, and use it to pass the value back and forth. Like so:
app.factory('basketDetail', function() {
return {
items: { basketCount: 0 },
getCount: function() {
//return something here
return 123;
}
}
});
function FooCtrl($scope, basketDetail) {
$scope.items = basketDetail.items;
$scope.items.basketCount = basketDetail.getCount();
}
function BarCtrl($scope, basketDetail) {
$scope.items = basketDetail.items;
}
<div ng-controller="FooCtrl">
{{items.basketCount}}
</div>
<div ng-controller="BarCtrl">
{{items.basketCount}}
</div>
This works because the $scope in both controllers is keeping a reference to the same object, which is maintained by your basketDetail service. But again, this isn't really the recommended way.
All of that said: $rootScope, IMO is most likely what you're looking for.
It doesn't require the creation of an additional controller.
It doesn't require the creation of any additional function references.
Will not cause the creation of any additional parent/child Scope nesting and subsequent watches.
No real need for $rootScope. Create a parent controller (e.g. RootController) with a function on its scope. The child scopes will automatically inherit it:
<div id="container" ng-controller="RootController">
...
function RootController($scope) {
$scope.item = {};
$scope.setBasketCount = function (detail) {
$scope.item.basketCount = detail.getCount();
}
}
In your detail controller you just use the setBasketCount() function:
function DetailController($scope, item, basketDetail) {
$scope.item = item;
$scope.setBasketCount(basketDetail);
//more code
}