angular.js get links from database - javascript

I'm using laravel 5 for backend and angular.js for frontend. App is completely driven by ajax requests.
I'm showing some static links(which would be always on any page visible) in my view like this:
<li ng-repeat="link in links">
{{link.name}}
</li>
What's the best way to handle this? My view doesn't contain .blade(because of angular) in name so I'm not able to load these links throw php.
Should I try to make some php workaround or load it in angular throw $http?
If in angular how should I get it into this config function?
app.config(function($routeProvider, $locationProvider) {
var links = ??; // http doesn't want to work here
links.map(function(item) {
$routeProvider.when('/'+item.url, {
..
});
});
});

I would suggest first to integrate the AngularJS to work together with blade template engine in Laravel. This can be done easy with angular service called interpolation.
Here is how you will make it:
<script>
var customInterpolationApp = angular.module('customInterpolationApp', []);
customInterpolationApp.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});
customInterpolationApp.controller('DemoController', function() {
this.label = "This binding is brought you by [[ ]] interpolation symbols.";
});
</script>
<div ng-app="App" ng-controller="DemoController as demo">
[[demo.label]]
</div>
Here is angularjs page explaning the $interpolateProvider
This way you will not have conflict between AngularJS and Blade Template Engine
You should load it with AngularJS
You should attach the result to a $scope.links in a custom AngularJS controller. Based on the code from step 1 you can inject $http into anonymous DemoController function, and after this inside controller do something like this:
var self = this;
$http.get('YOUR API LINK', function (data) {
self.links = data;
});

Related

AngularJS - make variable accessible to whole app

Below is a piece of code that connects with a Firebase database.
I have got a value for numberOfUsers and now I would like to use this variable in the html like so {{numberOfUsers}}.
I'm not really sure the best way to do this or if I need to use controllers also? Sorry if it's a stupid question, I'm still learning Javascript and Angular.
angular.module('myApp', ['ngRoute', 'firebase'])
var userList = new Firebase("https://my-app.firebaseio.com/presence/");
userList.on("value", function(snap) {
numberOfUsers = snap.numChildren();
console.log("Users = " + numberOfUsers);
});
;
http://jsfiddle.net/HB7LU/11820/
Any help will be much appreciated.
Thanks
The formal way to make a value available would be to put it in $rootScope, but it might be better to expose it as part of a service.
Try using constant
http://jsfiddle.net/HB7LU/11818/
var myApp = angular.module('myApp',[]);
myApp.constant('numUsers', 4);
function MyCtrl($scope,numUsers) {
$scope.name = 'Superhero';
$scope.numUsers = numUsers;
$scope.addUser = function(){
numUsers++;
$scope.numUsers = numUsers;
}
}
You can use a constant to achieve the same as Lucas suggested it. However, instead of creating a constant service for every value you can group then together like this :
angular.module("myModule")
.constant("CONST", { "KEY1" : "VALUE1",
"KEY2" : "VALUE2"});
This way you can gather a bunch of constants together and use it like:
CONST.KEY1
CONST.KEY2
EDIT: Your problem seems to be very different.
First of all you should use the AngularJS flavour of Firebase. Its called AngularFire. You can find out more about it here. I will answer the question of rendering the UI based on Model changes. AngularJS promotes the MVC pattern. You need objects of Service, Controller and View (HTML page) to achieve the functionality you want.
In the example I am providing below, everything is clubbed into one file (index.html) but ideally, the code should be separated.
<div ng-app="myapp">
<div ng-controller="PostCtrl" >
<ul>
<li ng-repeat="post in posts"> <!-- $scope.posts of PostCtrl" -->
<div>
<span>{{post}}</span> <!-- {{}} is used to render data -->
</div>
</li>
</ul>
</div>
<script>
//factory is a type of service. Services are used to write business logic or fetch data from the backend. Your Firebase related calls should come here.
angular.module("myapp", []).factory("myService", function($http) {
return {
fetchData: function() {
return [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; //can also be a request to the backend returning data.
}
};
});
//a controller connects a service to the HTML file. $scope service provided by AngularJS is used to achieve this.
angular.module("myapp").controller("PostCtrl", ["$scope", "myService", function($scope, myService) {
//posts variable is used in HTML code to retrieve this data.
$scope.posts = myService.fetchData();
}]);
</script>
</div>
To learn the basics of AngularJS you can go through codeschool tutorials. They are interactive and start from the basics.

How can I submit a new query in an angular application?

Let me start by saying this: this is my first forray into angularJS.
I am building an angular app with a feature where you can write sql directly against a database. Security issues aside (I am the only person who will be using this app when it is done).
I built a service on the backend that will return a json object result of whatever query is passed in as params[:query]['input'] (the backend is a rails app).
From the front end, I'd like to pass in a query parameter named input. So in the form on the angular app, I've created this form:
<form action="/path/to/service" method="post">
<textarea id="input" name="input"></textarea>
<button id="execute" name="execute">Execute Query</button>
</form>
However, this is not asynchronous, the page attempts to redirect and the data doesn't come in as it should.
Take a look at the AngularJS tutorial - REST and custom services, there you'll find what services provided by Angular you need to use to make an Ajax call. I suggest you read the whole tutorial if you didn't yet.
AngularJS is used for designing single page applications.
So once your application is loaded, the page won't get refreshed and all the server communication is done async using angular's feature $http.
If you want to submit any form, you can use $http like this
HTML:
<form ng-submit="sub()">
...
</form>
Then in your controller:
function ctrl($scope) {
$scope.sub = function() {
$http.post(url,data,headers)
.success(function(data,status,headers,config) {
//do something with data (response)
})
}
}
What you need is a controller and a factory. With the ng-click directive you call a function in the controller that calls a function in the factory. The factory returns a promise that the controller handles to put the result in the scope. Something like this:
var app = angular.module('app', []);
app.controller('mainCtrl', function($scope, dataService) {
$scope.getData = function(query){
var url = prepareYourURL(query) //HERE YOU PREPARE YOUR URL
dataService.getData(url).then(function(result){
$scope.data = result.data;
});
};
});
app.factory('dataService', function($http){
return {
getData: function(url) {
return $http.get(url);
}
};
});
And from your Html you call it like this:
<textarea ng-model="query"></textarea>
<button ng-click="getData(query)">Execute Query</button>
Then you can just present the data in the view as you like. Start by just doing this
<p>{{data}}</p>
and you will see everything you've fetched.

Originzational MVC and Angular keeping from injecting what I don't need

My problem is I have one ng-app. Does that mean I have to do dependency injection for plugins I may not be using on that given view? Example I bring in ngTagsInput does that mean I have to do it even when the view doesn't call for it? That would mean I have to include that js for every view even if it doesn't use ngTagsInput.
I have a very large MVC .NET application and I am trying to figure out what is he best way to handle bringing in external plugins.
I have some code like so in our Main _Layout template:
<html ng-app="ourApp">
<head>
<!-- all of our includes are here -->
</head>
<body>
<directive></directive>
<anotherdirective></anotherdirective>
#RenderBody()
</body>
</html>
RenderBody is where MVC slides in our views from our mvc routing.That view may look like so:
<script src="~/Scripts/HomeAngular.js"></script>
<div ng-controller="HomeCtrl">
<directive3></directive3>
</div>
App JS:
var app = angular.module('ourApp', ['ngTagsInput']);
IS there a way I can get around having to inject ngTagsInput on every view page even if i don't need it?
There are several different ways to handle Dependency Injection (DI) in angular. In this first example, you simply define ngTagsInput before declaring the controller. If ngTagsInput is a service, for example, you'll need to return an object with methods that allow you to access the data inside of that service.
For example:
app.service('ngTagsInput', function($scope) {
var data = {};
return {
getData = function() {
return data;
},
setData = function(val) {
data = val;
}
};
});
app.controller('HomeCtrl', function($scope, ngTagsInput) {
// ...
$scope.tags = ngTagsInput; // whatever you want to do with it
});
However, there's a problem...
In the example above, if you run that code through a minifier, you'll get $scope turned into some variable (a, b, x, etc...) and angular wont know what to do with that.
In this method, we use an array. The last item in your array is your lambda function for the controller, which takes 1 argument for each previous item in the array:
app.controller('HomeCtrl', ['$scope', 'ngTagsInput', function(scp, ngTagIn) {
// ...
}]);
This code can be run through a minifier just fine, since the dependencies are strings in the array and can be renamed to anything you want inside the function's parameters.
DI also works in directives, factories, filters, and services with the same syntax; not just controllers and modules.
app.directive('HomeCtrl', ['$scope', 'ngTagsInput', function(scp, ngTagIn) {
// ...
}]);
Couldn't you break down your application further into smaller modules instead of just one. Then you can inject the smaller modules into the app module and only inject the ngTagsInput dependency on the modules that actually need it. That's how I typically break up my application by function or area.

Resolve data for common controller angularjs

Just wanted to know if there is any way to resolve data for a controller not assigned with any route (BaseController common for all actions)
App.controller('BaseCtrl',function($http, Service){
$scope.data = null;
Service.getData(function(data){
$scope.data = data;
});
});
Can I can resolve Service.getData(); before the base controller is loaded and inject the same into it like
var Base = App.controller('BasCtrl', function($http, BaseData){
$scope.data = BaseData;
});
Base.resolve = {
BaseData:function(Service){
return Service.getData();
}
}
Please help if it is possible.
PS: I just want to prepare the data from service before the BaseCtrl is loaded and inject the same into it.
If your BaseCtrl is loaded with your home page then you have to fetch data before loading the javascript page containing BaseCtrl and put that into window.BaseData, other wise whichever controller is loaded first load data in there.
If basectrol is first page then you can implement it by immediately-invoked function in separate JS page and put that JS before BaseCtrl js file.
e.g. fetchdata.js
(function() {
window.BaseData= function() {...});
})();
You can access BaseData from your angular controller through Global parameter injected to your controller.
Now put files this order
<script src= "fetchdata.js"></script>
<script src="basecontroller.js"></script>
You see you have to break the rule to do that, but anyway Angular $resource in your Service is also nothing but Ajax implementation.

How to get json data and construct a modal using Angular JS

When I click on the view details button, I want to request JSON data and then construct a modal view over the content.
HTML:
View Details 1
View Details 2
View Details 3
Get JSON:
function MyCtrl($scope){
$http.get('json/story.json').success(function(data){
console.log(data);
$scope.story = data;
});
}
What is the best practices to run this MyCtrl function using angular.js when a user clicks on the detail button? Also the HTML above is being printed out using another controller. I hope there is some way to bind the clicks versus hard-coding ID's and such in the links.
You can call methods in your controller like this:
View Details
And then in the controller:
$scope.getDetails = function() {
$http.get(...).success(function(data){
$scope.story = data;
});
}
A complete example of CRUD edit with asynchronous data (here simulated via $timeout) can be seen here: http://plnkr.co/edit/EAabx4?p=preview
It uses the $dialog service from the http://angular-ui.github.com/bootstrap/ repository. This example uses Bootstrap's CSS but a template is fully customizable.
The nice part about the $dialog service is that it nativelly works with AngularJS promises so you don't have to copy things to a scope, use watches etc.
Put your server communication code (i.e., $http stuff) into an Angular service. Inject that service into the controller that displays your HTML and into your controller that is associated with your modal view (if you have one).
Have your links invoke functions on the controller that will interact with the service to fetch the data. Have your modal controller $watch for the data.
<div ng-controller="MyCtrl">
View Details 1
Controllers:
function MyCtrl($scope, myService) {
$scope.getDataset1 = function() {
myService.getDataset1(); // populates myService.modalData
};
}
function ModalCtrl($scope, myService) {
$scope.showModal = false;
$scope.$watch(myService.modalData, function(data) {
$scope.modalData = data;
$scope.showModal = true;
});
}

Categories

Resources