AngularJS selectively showing dynamic directives - angularjs

I created a few directives. When the page load all directives is loaded. All directives appear. I want to show directives when the function is called. For example when $scope.getConsultant is called the consultant directive must be appear. Other directives should not appear. I have too many html template but I didn't write here. How can I control? What is the best way?
Directives
<div class='container'>
<div consultant></div>
<div investment></div>
<div portfolio></div>
</div>
window.ngApp.directive('investment', function () {
return {
templateUrl: 'lib/view/investment.html'
};
});
window.ngApp.directive('consultant', function () {
return {
templateUrl: 'lib/view/consultant.html'
};
});
window.ngApp.directive('portfolio', function () {
return {
templateUrl: 'lib/view/portfolio.html'
};
});
AngularJS
var ngApp = angular.module('tapusor', []);
window.ngApp.controller('controllerHome', ['$scope', '$controller',
function ($scope, $controller) {
$scope.lat =25.33544;
$scope.lng =13.21687;
$scope.getConsultant = function () {
$.ajax({
type: 'post',
url: "/",
dataType: 'json',
data: {
lat: $scope.lat,
lng: $scope.lng
},
async: true,
cache: false,
success: function (data) {
$scope.resConsultant = data;
}
});
}
$scope.searchInvestment = function () {
$.ajax({
type: 'post',
url: "/",
dataType: 'json',
async: false,
cache: false,
data: {
lat:$scope.lat,
lng:$scope.lng
},
success: function (data) {
$scope.resInvestment = data;
}
})
}
$scope.portfolio = function () {
$.ajax({
type: 'post',
url: "/",
dataType: 'json',
async: false,
cache: false,
data: {
lat:$scope.lat,
lng:$scope.lng
},
success: function (data) {
$scope.resPortfolio = data;
}
})
}
}
]);

First, Satpal is right, use Angular builtins wherever possible.
You need some variable that you can key off of to determine which directive is currently being 'shown'. Then, on each one, you can use that with ng-if.
<div class='container'>
<div consultant ng-if="$shown == 'consultant'"></div>
<div investment ng-if="$shown == 'investment'"></div>
<div portfolio ng-if="$shown == 'portfolio'"></div>
</div>
This is just a rough example, but hopefully you get the idea.

I'd recommending restructuring this code to take advantage of an ngSwitch.
https://docs.angularjs.org/api/ng/directive/ngSwitch
If the goal is to have other directives not appear, then loading the data, and then using an ngSwitch will do just that.

Related

AngularJS - ng-repeat - using parent repeat data in child http request

I have what would seem to be a simple problem with AngularJS - apologies if so. I'm new and have searched all over and can't quite find an answer to what I want to do.
Basically I have a $http request that is getting a list of 'Cards' from a server which I'm then using ng-repeat to build in the HTML. I then want to populate those Cards with a number of 'Metrics' - also retrieved from the server. I have a controller for the 'Cards' (parents) and a separate controller for the 'Metrics' (children).
My issue is that I can't work out how to reference the ID of the parent 'Card' when making the child $http request.
Below is the HTML & JS that I am using - any help would be appriciated:
HTML:
<div class="Dashboard container-fluid" ng-controller="DahsboardCardController as Dashboard">
<div ng-repeat="Card in Dashboard.DashboardCards">
<div class="DashboardCard card">
{{Card.CardDisplayName}}
<div class="DashboardCardBody" ng-controller="DahsboardMetricController as Metric">
<div ng-repeat="Metric in Metric.DashboardMetrics">
{{Metric.MetricDisplayName}}
</div>
</div>
</div>
</div>
JS:
(function () {
var app = angular.module('OtterDashboard', [ ]);
app.controller('DahsboardCardController', [ '$http', function($http) {
//Declare a varaible for the data
var DashboardCards = this;
//Set the varaiable to an empty array to receive the data
DashboardCards.DashboardCards = [ ];
$http({
//Request the data
method: 'GET',
dataType: 'jsonp',
url: '/api.svc/tbl_Card',
useDefaultXhrHeader: false,
headers: {'Content-type': 'application/json'},
headers: {'Accept': 'application/json;odata=light;q=1,application/json;odata=verbose;q=0.5'},
crossDomain: true,
}).then(function successCallback(data) {
//The data was sucessfully received, populate the variable with it
DashboardCards.DashboardCards = data.data.d.results;
}, function errorCallback(response) {
//There was an error
console.log('Card data could not be retrieved');
});
}]);
app.controller('DahsboardMetricController', ['$http', function($http, Card) {
//Declare a varaible for the data
var DashboardMetrics = this;
//Set the varaiable to an empty array to receive the data
DashboardMetrics.DashboardMetrics = [ ];
$http({
//Request the data
method: 'GET',
dataType: 'jsonp',
url: '/api.svc/DashboardMetric?Card=%27' + **???reference to parent card ID???** + '%27',
useDefaultXhrHeader: false,
headers: {'Content-type': 'application/json'},
headers: {'Accept': 'application/json;odata=light;q=1,application/json;odata=verbose;q=0.5'},
crossDomain: true,
}).then(function successCallback(data) {
//The data was sucessfully received, populate the variable with it
DashboardMetrics.DashboardMetrics = data.data.d.results;
}, function errorCallback(response) {
//There was an error
console.log('Metric data could not be retrieved');
});
}]);
})();
Thank you!
EDIT 1
Use a service for shared variable between controllers. Look the example:
app.controller('DahsboardCardController', ['$http', function($http, $sharedResource) {
var DashboardCards = this;
DashboardCards.DashboardCards = [ ];
$http({
method: 'GET',
dataType: 'jsonp',
url: '/api.svc/tbl_Card',
useDefaultXhrHeader: false,
headers: {'Content-type': 'application/json'},
headers: {'Accept': 'application/json;odata=light;q=1,application/json;odata=verbose;q=0.5'},
crossDomain: true,
}).then(function successCallback(data) {
DashboardCards.DashboardCards = data.data.d.results;
$sharedResource.set("id", "<pass id value>");
}, function errorCallback(response) {
console.log('Card data could not be retrieved');
});
}]);
app.controller('DahsboardMetricController', ['$http', function($http, Card, $sharedResource) {
var DashboardMetrics = this;
DashboardMetrics.DashboardMetrics = [];
$http({
method: 'GET',
dataType: 'jsonp',
url: '/api.svc/DashboardMetric?Card=%27' + $sharedResource.get("id") + '%27',
useDefaultXhrHeader: false,
headers: {'Content-type': 'application/json'},
headers: {'Accept': 'application/json;odata=light;q=1,application/json;odata=verbose;q=0.5'},
crossDomain: true,
}).then(function successCallback(data) {
DashboardMetrics.DashboardMetrics = data.data.d.results;
}, function errorCallback(response) {
console.log('Metric data could not be retrieved');
});
}]);
app.factory('$sharedResource', function () {
var property = {};
return {
get: function (key) {
return property[key];
},
set: function(key, value) {
property[key] = value;
}
};
});
EDIT 2
When working with angularjs is recomended use a one object for print object in table. Why this is a beautiful s2.
Look this example. To help you in development. Use the sample function pass the parentId in load(CardId). This function will run in the page load.
I too fix code html. You used the alias controller before input field of same.
var app = angular.module("App", []);
app.controller('DahsboardCardController', ['$scope', function($scope) {
$scope.DashboardCards = [{
CardId: "111",
CardDisplayName: "Card 1"
}, {
CardId: "222",
CardDisplayName: "Card 2"
}, {
CardId: "333",
CardDisplayName: "Card 3"
}];
}
]);
app.controller('DahsboardMetricController', ['$scope', function($scope) {
$scope.load = function(CardIdParent) {
console.log(CardIdParent);
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="App" class="Dashboard container-fluid" ng-controller="DahsboardCardController as Dashboard">
{{Dashboard.DashboardCards}}
<div ng-repeat="Card in DashboardCards">
<div class="DashboardCard card">
{{Card.CardDisplayName}}
<div class="DashboardCardBody" ng-controller="DahsboardMetricController as Metric" ng-init="load(Card.CardId)">
This a id parent: {{Card.CardId}}
<div ng-repeat="MetricItem in DashboardMetrics">
{{MetricItem.MetricDisplayName}}
</div>
</div>
</div>
</div>
</div>

Child View/Route that Resolves from Different Service than Parent

I'm having an issue loading a child view/route while resolving a GET from a different service from the parent view/route.
Within the parent view, each ion-item links to /#/tab/categories/{{ category.listing_category_id }}
When clicked the URL populates (for a flash) with the correct category ID, the child's service successfully receives the category ID, runs the subsequent GET request & returns the data as a promise...that all works as intended. The issue is that the child view/route never loads. All help/guidance is very much appreciated.
Parent
angular.module('rainbowPages.tab.categories', [])
.config(function($stateProvider, $urlRouterProvider) {
// UI Router
$stateProvider.state('tab.categories', {
url: '/categories',
views: {
'tab-categories': {
templateUrl: 'views/tab-categories/tab-categories.html',
controller: 'CategoriesCtrl'
}
}
});
// otherwise
$urlRouterProvider.otherwise('/tab/categories');
})
.factory('CategoriesService', function($resource) {
var remoteCategoriesURL = 'http://104.167.104.163:7000/api/v1/categories',
categoriesService = $resource(remoteCategoriesURL, {}, {
getAll: {
method: 'GET',
isArray: true
}
});
return categoriesService;
})
.controller('CategoriesCtrl', function($scope, CategoriesService) {
$scope.categories = CategoriesService.getAll();
});
Child
angular.module('rainbowPages.tab.categories.detail', [])
.config(function($stateProvider, $urlRouterProvider) {
// UI Router
$stateProvider.state('tab.category-detail', {
url: '/categories/:listing_category_id',
views: {
'tab-categories': {
templateUrl: 'views/category-detail/category-detail.html',
controller: 'categoryDetailCtrl'
}
},
resolve: {
listings: function($stateParams, CategoryDetailService) {
// bind data to listing
return CategoryDetailService($stateParams.listing_category_id);
}
}
});
})
.factory('CategoryDetailService', function($resource) {
var remoteCategoryURL = 'http://104.167.104.163:7000/api/v1/category/:categoryID',
categoryDetailService = $resource(remoteCategoryURL, {categoryID:'#listing_category_id'}, {
get: {
method: 'GET',
isArray: true
}
}),
getListingsInCategory = function getListingsInCategory(categoryID) {
listingsInCategory = categoryDetailService.get({categoryID:categoryID}, function(promise) {
if(promise.$resolved = true) {
console.log(promise); // how I know the promise has the correct data
return promise;
}
});
};
return getListingsInCategory;
})
.controller('categoryDetailCtrl', function($scope, listings){
console.log('listings are : ' + listings);
$scope.listings = listings;
});

No data returned in consuming REStful web service using Angularjs

I am beginner learning Angularjs .Please help me with examples for following
script added
javascript -
var app = angular.module('myapp', []);
app.controller('MyCtrl1', ['$scope', 'UserFactory', function ($scope, UserFactory) {
UserFactory.get({}, function (userFactory) {
$scope.time = userFactory.time;
})
}]);
var service = angular.module('apiService', ['ngResource']);
service.factory('UserFactory', function ($resource) {
return $resource('http://time.jsontest.com', {}, {
query: {
method: 'GET',
params: {},
isArray: true
}
})
});
.html file
<body ng-app="myapp">
<divng-controller="MyCtrl1" >
<p>
Result from RESTful service is: {{ time }}
</p>
</div>
</body>
above snippet gives the out put as
Result from RESTful service is : {{time}}
and not the value i am expecting
..Reference : http://draptik.github.io/blog/2013/07/13/angularjs-example-using-a-java-restful-web-service/
I want to write CRUD methods (GET/POST/PUT/DELETE) and I have started with GET.
Thanks
You need to make sure that your main app module injects your service. In your plnkr you have:
var app = angular.module('myapp', []);
where you should really have:
var app = angular.module('myapp', ['apiService']);
This ensures that the service module is injected into your app module, and you can use the UserFactory that you define in that module. For this simple case you could have also simply defined the UserFactory factory on the 'myapp' module as well
It's very close but you have a slight mistake in your app instantiation. It should be the following:
var app = angular.module('myapp', [ 'apiService' ]);
There's a couple other issues I see as well but one thing is I usually do the following for async requests
var promise = UserFactory.get({}).$promise;
promise
.then( function(response) {
$scope.time = userFactory.time;
});
EDIT: Here's an example for named methods for a given ReST service:
return $resource('/api/v2.0/user/lists/:listId',
{},
{
// POST - list create/product addition to list
'addProduct': {
method: 'POST',
isArray: false,
params: {
listId: '#listId',
productId: '#productId'
}
},
'createList': {
method: 'POST',
isArray: false,
params: {
listName: '#listName'
}
},
// GET - list of user lists/list details
'readLists': {
method: 'GET',
isArray: false,
params: {}
},
'readListsWithProductId': {
method: 'GET',
isArray: false,
params: {
productId: '#productId'
}
},
'readListById': {
method: 'GET',
isArray: false,
params: {
listId: '#listId',
sort: '#sort',
flags: true,
extendedInfo: true,
rows: '#rows',
start: '#start'
}
},
// PUT - list renaming
'renameList': {
method: 'PUT',
isArray: false,
params: {
newName: '#listName',
listId: '#listId'
}
},
// DELETE - list deletion/clear/product removal
'removeProduct': {
method: 'DELETE',
isArray: false,
params: {
listId: '#listId',
productId: '#productId'
}
},
'clearList': {
method: 'DELETE',
isArray: false,
params: {
listId: '#listId',
clear: true
}
},
'deleteList': {
method: 'DELETE',
isArray: false,
params: {
listId: '#listId'
}
}
});
You could access it like the following:
Factory.[methodName](payload)

using the variables from factory tu update the content

I am trying to understand the logic of this factory thing. How can I use those variables, like save, drop, update. Can i use them like this ? X . Or i have to write something else to success.
app.factory("Inventory", function($resource){
return $resource(
"http://localhost/api/v1/inventory/:Id",
{Id: "#Id"},
{
update: {
method: 'POST',
params: {"update": true},
isArray: false
},
save: {
method: 'PUT'
},
create: {
method: 'POST'
},
drop: {
method: 'DELETE'
}
}
);
});
You need to define a controller and inject the dependency on it for you to be able to use this factory.
Example:
app.controller('myController', function($scope, Inventory) {
$scope.drop = Inventory.drop;
});
in your html:
<div ng-controller='myController'>
X
</div>

Error: Unknown provider: employeesProvider <- employees

I am having a heck of a time trying to figure out why I'm getting the Unknown provider error in Angular. I've checked every other question I could find on the subject and most suggest an error in dependency injection. However, it doesn't seem to me like I'm forgetting to inject anything. I've been trying to get the resolve property to work like this post by Misko. I'm able to console log out the employee data after it's resolved, but then I get the Unknown provider error, which prevents the data from being shown on the page.
Here is my router:
"use strict";
var app = angular.module('app',[
'employeeServices'
]);
app.config(appRouter);
function appRouter ($routeProvider) {
$routeProvider
.when('/employees/:account_id', {
controller: 'EmployeeCtrl',
templateUrl: 'view/employee/view.html',
resolve: employeeCtrl.resolve
})
.otherwise({ redirectTo: '/' });
}
Here is my controller
var employeeCtrl = app.controller('EmployeeCtrl', [
'$scope',
'employees',
function ($scope, employees) {
$scope.employee = employees;
console.log($scope.employee);
}
]);
employeeCtrl.resolve = {
employees: function (Employee, $q, $route) {
var deferred = $q.defer();
console.log("current params: ", $route.current.params.account_id);
Employee.getOne({ id: $route.current.params.account_id }, function (successData) {
deferred.resolve(successData);
}, function (errorData) {
deferred.reject(errorData);
});
return deferred.promise;
}
};
And my factory:
angular.module('employeeServices', ['ngResource'])
.factory('Employee', ['$resource', function ($resource) {
return $resource('/employees/:id/json',
{
id: '#account_id'
},
{
'save': {
method: 'POST',
isArray: false
},
'update': {
method: 'PUT',
params: {
id: '#account_id'
}
},
'remove': {
method: 'DELETE',
params: {
id: '#account_id'
}
},
'getOne': {
method: 'GET',
params: {
id: '#account_id'
},
isArray: false
},
'query': {
method: 'GET',
params: {
id: '#account_id'
},
isArray: true
}
}
);
}]);
Any suggestions would be so greatly appreciated!
So the problem was that I was setting up the EmployeeCtrl controller through ng-controller inside my partial's view, like so:
<div class="viewPage" ng-controller="EmployeeCtrl">
When using resolve, however, the controller set up must be done through the router in order for it to be available at runtime. I removed the ng-controller="EmployeeCtrl...
<div class="viewPage">
... and presto, like nothing ever happened.
I have to note that I received help from the kind, patient folks over on the AngularJS IRC channel...
Since you defined the factory called Employee, you should use the exact name to refer to this module when you inject it to the controller.
var employeeCtrl = app.controller('EmployeeCtrl', [
'$scope',
'employees',
Change to
var employeeCtrl = app.controller('EmployeeCtrl', [
'$scope',
'Employee',

Resources