Dynamically generated navbar and AngularJS - javascript

I could not find an easy way to explain the following, so I apologize if it is not clear enough.
I have a navigation bar where each item is a category of articles. The navigation item are read from database and can be modified from the back-office.
I get the categories via a AngularJS controller :
app.controller('ApiController', ['$scope', '$http', function($scope, $http) {
$http.get('/categories')
.success(function(categories) {
$scope.categories = categories;
});
}]);
<div class="collapse navbar-collapse" id="target-navbar-main">
<ul class="nav navbar-nav">
<li ng-repeat="category in categories">
<% category.name %>
</li>
</ul>
</div>
In the body of the page, I am using another controller to get articles of a given category but I can't find a way to make the navbar communicate with the articles controller and pass the category of the clicked button.
Thanks for help

I think what you want for the API is a service not a controller. Generally in Angular controllers aren't meant to be sending a bunch of data between each other. Central sets of calls and communications that multiple controllers depend on are put into services. If you were to extract your API calls to a service you could inject that service into that controllers that need to deal with it as necessary. But without seeing more of the code in question it's hard to recommend a good way to do that.

Related

Render JSON with Angular

Can someone please explain and show, how I can render a complex JSON object with Angular.
I am making a call to the FourSquare API which returns a list of recommended venues based on my search(location). The JSON file is huge and am finding it difficult to render out the relevant data in it.
Here is what my JSON looks like:
https://developer.foursquare.com/docs/explore#req=venues/explore%3Fnear%3DEarlsfield
Here is the function in my controller which makes a call to the url.
Note; baseurl = the url i built up with my AccessId and Secret
//Get response from server
function fetch(){
$http.get(baseurl + $scope.search)
.success(function(response){
console.log(response.response.groups[0].items);
$scope.details = response;
});
I would then like to be able to render out my results in an ul with lis. Each LI would have the name of the venue as well as other information. At the moment I have the following:
<div ng-if="!details">
Loading...
</div>
<div ng-if="details.Response==='True'">
<ul ng-repeat='groups in response'>
<li>{{item.name}}</li>
<li>{{item.address}}</li>
</ul>
</div>
<div ng-if="details.Response==='False'">
No results found.
</div>
CODEPEN LINK:
http://codepen.io/AntonioVassilev/full/EVrKxp/
I am a novice in Angular and am finding it confusing browsing through large data objects like this one. Help appreciated
The details is a Object and you can't loop on it. Fetch groups first: like details.groups
JSON structure: http://screencloud.net/v/Oqd
Some example:
<ul ng-repeat='group in details.groups'>
<li>{{group.name}}</li>
<li>{{group.type}}</li>
<ul ng-repeat='item in group.items'>
<pre>{{item}}</pre>
</ul>
Some demo you can play with
You should be repeating on your scope variable (scope.details). According to your js the correct ng-repeats seem to be sth like this:
<div ng-repeat='groups in details'>
<div ng-repeat='group in groups'>
<ul ng-repeat='item in group.items'>
<li>{{item.name}}</li>
<li>{{item.address}}</li>
</ul>
</div>
</div>

View is getting initialized again and again

I'm building a dashboard similar to this one Admin Dashboard Theme
I'm implementing the Right Side SideBar as show in the screenshot
My App code structure is something like:
index.html:
<div ui-view=""></div>
main.html
<div ui-view=""></div>
<div ng-include='"app/dashboard/sidebar.html"'></div>
I have done nesting of view in my main.html where I'm injecting different views. Also, since my right side sidebar is fixed, I want it to be common in all the main views. So, I have just included it in my main.html.
Now, the problem is somehow my sidebar.html is getting initialized again and again no matter if I scroll my page down or perform any action inside sidebar. I have verified it by printing console logs for every controller function which are used in sidebar.html view.
This problem is related to my this post: Earlier, I wasn't able to figure out the actual issue.
Following is my controller and jade code:
angular.module('myApp')
.controller('SidebarCtrl', function($scope, $rootScope) {
$scope.message = {};
$scope.addSideBarToggleClass = function() {
console.log("addSideBarToggleClass");
return true;
}
$scope.getStatusClass = function(status) {
console.log("getStatusClass");
return 'is-online';
}
$scope.openChat = function(receiver) {
console.log("openChat");
}
// etc...
});
<aside ng-class="{ 'control-sidebar-open' : addSideBarToggleClass()}"
ng-controller="SidebarCtrl">
<ul>
<li ng-class="{active: isTabSelected('chat')}">
<a data-toggle="tab" ng-click="updateCurrenTab('chat')"></a>
</li>
<li ng-class="{active: isTabSelected('home')}">
<a data-toggle="tab" ng-click="updateCurrenTab('home')"></a>
</li>
</ul>
<div>
<div ng-class="{active: isTabSelected('home')}">
<h3>Recent Activity</h3>
</div>
<div ng-class="{active: isTabSelected('chat')}">
<div>
<h4>Chat {{noOfUsersOnline}}</h4>
<div>Friends
<a href="#" ng-repeat="user in users" ng-click="openChat(user)">
<span ng-class="getStatusClass(user.status)"></span>
{{user.name}}</a>
</div>
</div>
</div>
</div>
</aside>
I see many logs of "addSideBarToggleClass", "getStatusClass" and every time I click on openChat, I see a log of "openChat" and then again "addSideBarToggleClass" and "getStatusClass"
Can anyone please point out what can be the possible problem for this behavior?
You need to familiarize yourself with the concept of a digest loop in Angular.
In short, every time a digest loop runs, all expressions, e.g. {{name}} or ng-show="isActive && isEnabled", that are being "$watched" by Angular are evaluated (sometimes more than once). This means that if you are invoking a function inside an expression:
<div ng-show="isShown()">
$scope.isShown = function(){
console.log("expect to see this text a lot of times");
return true;
};
the function will be executed on every digest loop.
A digest loop runs any time that something in Angular calls $scope.$digest, which by default happens on things like ng-click or ng-change or $http.then, etc..

(angularJS) make ng-click open a link on an ng-repeat

New to Angular, so sorry if this has been covered somewhere but it's hard for me to explain exactly what I want in succinct terms.
Currently I have an ng-repeat pulling data from a JSON object and making a list.
<li ng-click="openLink()" ng-repeat="location in locations">
{{location.name}}
</li>
Each object has a key called "link" and that key has a property that is a url. I want the function openLink() to open the link associated with each object. I'm not sure how to go about this in the controller.
I know i can do
<li ng-click="openLink()" ng-repeat="location in locations">
<a ng-href="{{location.link}}">{{location.name}}</a>
</li>
but i'd like to be able to do it with ng-click instead to keep the index.html cleaner. So what do I put in here to accomplish the same thing?
$scope.openLink = function() {
};
If the url that you want to redirect to is a route in your angular app, you need to inject the $location service into the controller, then in your function, set the path property on $location.
<li ng-click="openLink(location)" ng-repeat="location in locations">
{{location.name}}
</li>
$scope.openLink = function(location){
$location.path(location.link);
}
If the location link is a complete url, you should inject the $window service into your controller, and change the openLink function to set $window.location.href.
$scope.openLink = function(location){
$window.location.href = location.link;
}

AngularJS $scope data not rendering in view

I have been struggling with this problem for the past few days, and now i believe its time to reach out to the community for some help.
I am creating a website using the MEAN stack, this is my first time using Angular JS so i am a noobie.
The problem I am having is, I am not able to render ANY $scope data in my view. this has been driving me crazy because the AngularJS chrome debugger shows that the $scope data is there!!! But it wont render in my template.
App Structure
/public
/js
/controllers
-user.js
-app.js
/views
-index.html
Contents of my html - i will not copy entire file, only angular parts.
<!doctype html>
<html ng-app="PCT">
<div ng-controller="userController" class="column">
<a class="dropdown-toggle" data-toggle="dropdown" href="#userinfo" >
<img ng-src="{{user.img}}" style="width:40px; height:50px;" />
</a>
<ul class="dropdown-menu" role="menu">
<li><strong>{{user.name}}</strong></li>
<li><a ng-click="logOut()">Sign Out</a></li>
<li>Admin Site</li>
</ul>
</div>
<script src ="js/app.js"></script>
<script src="js/controllers/user.js"></script>
Contents of my app.js
angular.module('PCT.userController',[]);
//Importing all modules into main module
angular.module('PCT',['PCT.userController']);
Contents of my user.js (Controller)
angular.module('PCT').controller('userController', ['$scope', function($scope){
$scope.user = {
img : 'http://path/to/usr/img/user.jpg',
name : 'mcutalo'
};
$scope.logOut = function(){
console.log('logging out');
}
}]);
I am able to click on the Logout button in my menu, and this will trigger the console log, so it is making it to the controller. But it wont display my $scope data at all.
I am not sure what your question was, but if "PCT" is your module (it should match the name ng-app and the app.module("PCT") and no need to inject controller if u are defining controller using
angular.module('PCT').controller('userController', ['$scope', function($scope){
}]);
Here is the plnkr of the working one.
Updated with the Logout and it is called console.log...
http://plnkr.co/edit/uSLVqEayCh2XeeGI7LZe?p=preview
Let me know if any further help is needed.

Ember.js outlets and routes

I've been trying to learn Ember.js for the last two weeks and I've really struggled. I'm hoping for an 'a-ha' moment but each new feature I try to implement always results in hours of failed testing. I just don't seem to be grasping the framework. I feel like I'm working against it. I'm hoping someone can explain a path forward through this simple example.
I am creating a web app that allows the user to pick products that they will sell to a client. There is a list of products they can chose from and then a list of products they've selected.
I imagine a left-column with navigation controls and a main column showing either the selected products or new products they can add to the order. Here is the basic template:
<script type="text/x-handlebars" data-template-name="pc">
<div id="nav">{{outlet nav}}</div>
<div id="main">{{outlet main}}</div>
</script>
Here is the left navigation template:
<script type="text/x-handlebars" data-template-name="nav">
<div class="button">{{#linkTo "pc.add"}}Add Products{{/linkTo}}</div>
</script>
Here is the selected products template:
<script type="text/x-handlebars" data-template-name="selectedProducts">
{{#each p in controller}}
<div class="product">
<h4>{{p.name}}</h4>
</div>
{{/each}}
</script>
Here is the available products template:
<script type="text/x-handlebars" data-template-name="addProducts">
<div id="addProducts" class="addProducts">
{{#each p in controller}}
<div class="product">
<h4>{{p.name}}</h4>
</div>
{{/each}}
<button {{action "addSelectedProducts"}}>Add Selected Products</button>
<button {{action "back"}}>Back</button>
</div>
</script>
I can load the 'pc' template with some already selected products. Great. I can also navigate to the 'Add Products' template. Great. But when I click 'Add Selected Products', I can't figure out how to move the selected products into the controller/model behind the 'Selected Products' template and then get that template to re-render in place of the 'Add Products template'. It's really two question. How do I update the model of another controller from within a different controller? And, how do I then transition from an event to another route?
Can someone show me how you would design the Route(s) and Controllers? I know that's asking a lot. I"m mostly interested in seeing how you respond to an event in the AppProductsController, update SelectedProductsController's model, and then transition to SelectedProductsRoute and have it re-render the template.
I want to believe this is an amazing framework but I just keep hitting walls.
Andrew
How do I update the model of another controller from within a different controller?
Connect controllers using the needs property. So something like:
//in AddProductsController
needs: ['selectedProducts']
addSelectedProducts: function() {
// Now selectedProductsController can be accessed via the controllers property
otherController = this.get('controllers.selectedProducts');
// add the selected ones...
}
See http://emberjs.com/guides/controllers/dependencies-between-controllers/
how do I then transition from an event to another route?
//in AddProductsController
this.transitionToRoute('blogPosts');
See http://emberjs.com/api/classes/Ember.Controller.html#method_transitionToRoute

Categories

Resources