Angularjs change view without a click - angularjs

I am stil new to Angular, but trying, very hard, to get my head round it.
Basically, I just want to move from one view, to another one function is complete. Here is the code:
App.controller('clientLogin', function ($scope, $http, $route) {
$scope.clientLoginBt = function () {
var sun = $('#ClientUsername').val();
var spa = $('#ClientPassword').val()
$http({url: "/sources/",
headers: {"X-Appery-Database-Id": dbid},
params: {where: '{"$and" : [{"username": "' + sun + '"}, {"password" : "' + spa + '"}]}'}})
.success(function (data) {
console.log(data.length);
$scope.clientLogggedin = data;
if (data.length > 0) {
$route.clientLogggedin();
} else {
}
})
.error(function (status) {
console.log('data on fail: ' + status);
});
}
});
Above, if the data comes back with more than one row, the user log is correct, and I just want to change view!
I have tried $location, did not work, and as Angular is really simple to use, in the amount of coding, I cannot see any info on it, other than if you click, it starts a controller.
Here is the HTML:
<div class="row" ng-controller="clientLogin">
<div class="large-12 medium-12">
<input type="text" id="ClientUsername" placeholder="Enter Username" />
<input type="password" id="ClientPassword" placeholder="Enter Password" />
<button ng-click="clientLoginBt()">Login</button>
</div>
</div>
The page I am looking to jump to, within the is called clientLoggedIn.html.
I have also added it to the config, thinking i could access it with $route :
App.config(function ($routeProvider) {
$routeProvider
.when('/',
{
templateUrl: 'views/home.html'
})
.when('/userLogin', {
templateUrl : 'views/userLogin.html',
controller: 'userLoginController'
})
.when('/clientLogin', {
templateUrl : 'views/clientLogin.html',
controller: 'clientLoginController'
})
.when('/clientLoggedIn', {
templateUrl : 'views/clientLoggedIn.html',
controller: 'clientLoggedInController'
})
.otherwise({
redirectTo : '/'
}
);
});
Any ideas on what I am doing wrong please ?
Thanks in advance.

Using path method of $location should do the trick. Since you want to get to clientLoggedIn.html, you would need to use the matching route (/clientLoggedIn):
$location.path("/clientLoggedIn");
Be sure that $location service is injected into your App Controller. This is the line you should probably replace with what I have above:
$route.clientLogggedin();

It is just a matter of checking an indicator whether the $http call was successful or not. If you are not willing to add a routing for clientLoggedIn.html. You can do something like below, just to enable the logged in page:
<div class="row" ng-controller="clientLogin">
<div class="large-12 medium-12" ng-hide="sucessfulLogin">
<input type="text" id="ClientUsername" placeholder="Enter Username" />
<input type="password" id="ClientPassword" placeholder="Enter Password"/>
<button ng-click="clientLoginBt()">Login</button>
</div>
<ng-include src="'views/clientLoggedIn.html'" ng-show="sucessfulLogin">
</ng-include>
<!-- or just include the DOM element here if you do not
want a separate html altogether-->
</div>
and in the REST call:
if (data.length > 0) {
//Assuming the flag in pre-initialized to false in controller
$scope.sucessfulLogin = true;
} else {
}
Also note, using ng-include directive you can still use a separate controller in clientLoggedIn.html if you are willing to. Just have to use ng-controller in the first element inside clientLoggedIn.html.

Related

passing data to another page angular js

I am new to Angular js and want to pass the data from a submit to another page.
How can I make this in angularjs?
I can add lists to a single customer, but I can display the data only in the same page.
I want to display the data in another page after the submit.
I have learnd today, how to use the services, but still I can not pass data from a page to another.
Can anyone help me with a example?
Sorry for my bad English and thank you
// ngRoute code
var app = angular.module('appCheck', ['ngRoute', 'angularUtils.directives.dirPagination']);
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
.when("/", {
controller : "customersCTRL",
templateUrl : "/app/customers/customers.html"
})
.when("/customers", {
controller : "customersCTRL",
templateUrl : "/app/customers/customers.html"
})
.when("/lists", {
controller : "listsCTRL",
templateUrl : "/app/lists/lists.html"
})
.otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix('!');
}]);
// controller code
$scope.getList = function(id) {
listsService.getSingleCustomer(id)
.then(function successCallback(response, data) {
//$scope.clearForm();
$scope.customer = response.data[0].name;
$scope.id_customer = response.data[0].id;
//$scope.getAll();
//console.log(id);
})
}
$scope.createList = function createList() {
listsService.createList()
.then(function successCallback(response, data) {
$('#addLists').modal('hide');
$scope.clearForm();
})
};
// services code
this.createLists = function() {
return $http.post('/lists/add' , {
"name" : $scope.name,
"id_customer" : $scope.id_customer
})
}
<button ng-click="getListExample(x.id)" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#addL"><span class="glyphicon glyphicon-plus" aria-hidden="true"> Add List</span></button>
<h4 class="modal-title">Add Liste for the customer <span contenteditable="false" ng-bind="cust"></span></h4>
<label>Name of the List</label>
<input type="text" ng-model="name">
<button type="button" ng-click="createListExample()" class="btn btn-primary">Create</button>
You shouldn't pass data. Instead, the other page should get the data it needs to show, from the backend, based on the path parameters.
So the path for the list of customers should be /customers. The associated component gets the list of customers from the backend.
Then, to display a single customer, you would go to /customers/:customerId (example: /customers/42). The componenty would get the details of the customer 42 from the backend.
To display the lists of the customer 42, for example after you have added a list to that customer, you would go to /customers/:customerId/lists (example: /customers/42/lists). The component would get the lists of the customer 42 from the backend.

Search Toolbar with AngularJS

This is a newbie question about Angular 1.4.
My Main Question
I have the following search view:
'use strict';
var module = angular.module('myapp.search', ['ngRoute', 'ngResource']);
module.config(function ($routeProvider) {
$routeProvider.when('/search', {
templateUrl: 'search/search.html',
controller: 'SearchCtrl'
});
});
module.factory('Search', function ($resource) {
return $resource('http://www.myapp.com/api/search', {}, {
query: {
method: 'GET',
params: {},
isArray: false
}
});
});
module.controller('SearchCtrl', function ($scope, Search) {
$scope.results = [];
$scope.query = '';
$scope.doSearch = function (query) {
Search.query({q: query}).$promise.then(function (result) {
$scope.results = result.results;
});
};
});
And the partial HTML (search.html):
#search.html
<input placeholder="search" ng-model="query" />
<button ng-click="doSearch(query)" />
<h1>Results</h1>
<ol>
<li ng-repeat="result in results">{{ result }}</li>
</ol>
...
This works perfectly, the problem is when I want to put the search input in a toolbar (defined in index.html):
#index.html
<div ng-controller="SearchCtrl">
<div class="toolbar">
<input placeholder="search" ng-model="query" />
<button ng-click="doSearch(query)">
</div>
...
In this case, by pushing the search button the query is executed in the back-end but the results are not updated in $scope. what's wrong? I've tried calling $scope.$apply() with no luck. I'm lost with this.
Bonus Question
Given that the search functionality is in the toolbar (always visible) users can execute queries in any place of the website. How can I redirect the response to http://www.myapp.com/search?
Thanks in advance.
You have two distinct instances of SearchCtrl, each with its own distinct scope: one in the navbar (dur to ng-controller="SearchCtrl"), and one in the main view (due to controller: 'SearchCtrl').
So the search in the navbar modifies the scope of the navbar controller, and the scope of the main view doesn't know anything about it.
If you want to got to the search main view when something is searched in the navbar, simply use
$location.url('/search?query=' + theEncodedQueryTypedByTheUser);
And in the search route's resolve function, or in its controller, get the route param named query, send the HTTP request, and update the scope with the results.

How to send data from one controller to another controller in angularjs

Below is my playlist json data coming from playlist controller.
{
"id":18,
"file":{"url":"/uploads/playlist/file/18/01_-_MashAllah.mp3"},
"event_id":23,"created_at":"2015-11-11T10:33:52.000Z",
"updated_at":"2015-11-11T10:33:52.000Z",
"name":"01 - MashAllah.mp3"
},
{
"id":19,
"file":{"url":"/uploads/playlist/file/19/02_-_Laapata.mp3"},
"event_id":19,"created_at":"2015-11-11T10:50:01.000Z",
"updated_at":"2015-11-11T10:50:01.000Z",
"name":"02 - Laapata.mp3"
}
Now i want to bind id and name to a playerController am i doing something like this
<div ng-controller="playlistsController">
<div ng-repeat="playlist in playlists">
<div ng-controller='PlayerController'>
<input type=hidden ng-model="ID" ng-init="ID=playlist.id">
<input type=hidden ng-model="Name" ng-init="Name=playlist.name">
</div>
</div>
</div>
and in controller
.controller('PlayerController',['$scope',function($scope) {
console.log($scope.ID);
console.log($scope.name);
}]);
but the console is showing undefined.
i don't know where i am going wrong as i am new to angular.
METHOD 1:
The best way to share data between controllers is to use services. Declare a service with getters and setters and inject into both the controllers as follows:
service:
app.service('shareData', function() {
return {
setData : setData,
getData : getData,
shared_data : {}
}
function setData(data) {
this.shared_data = data
}
function getData() {
return this.shared_data
}
})
With your service defined, now inject into both the controllers and use the parent controller (in your case) to set the data as follows:
app.controller('playlistsController', function(shareData) {
//your data retrieval code here
shareData.setData(data);
})
And finally in your child controller, get the data:
app.controller('PlayerController', function(shareData) {
$scope.data = shareData.getData();
})
METHOD 2:
Since, you have to communicate data from parent controller to child controller, you can use $broadcast as follows:
parent controller:
//retrieve data
$scope.$broadcast('setData', data);
And receive the data in child controller:
$scope.$on('setData', function(event, args) {
$scope.data = args;
})
First controller code is executed, then angular starts proceed html this controller is attached to. So just move your variable initialization to controller:
$scope.Name = $scope.playlist.name;
$scope.ID = $scope.playlist.id;
or just use original variables (if you dont need copy of them)
<input type=hidden ng-model="ID=playlist.id">
<input type=hidden ng-model="Name=playlist.name">
or you may leave it as is - it works disregarding that you don't see values in log.
You should use $parent:
JSFiddle
HTML:
<div ng-controller="playlistsController">
<div ng-repeat="playlist in playlists">
<div ng-controller='PlayerController'>
<input type="text" ng-model="$parent.playlist.id">
<input type="text" ng-model="$parent.playlist.name">
</div>
</div>
</div>
JS:
app.controller('PlayerController', function ($scope, $sce) {
console.log($scope.$parent.playlists);
});

Why angularjs controller is not called when i click the button again?

Hi i have a webpage like this,
left side has button,
right side is the area for ng-view (in my case, several checkboxes and submit button)
When i click the button, it'll
1. using the route provider, it'll reach its controller and template URL.
2. The controller will query some info from back end side (node.js)
3. The info above will be used by template URL to display initial checkbox options.
Now this procedure works fine for the 1st time. But when i click the button again, i was hoping it'll call its controller again, but from debugger, seems nothing happened, controller is not called.
So very confused, why is this please ???
in the server side,
app.get('/2getMyDiagValue', function(req, res)
{
console.log("get my diag");
var v1=0, v2=0;
var shellCmd = "... some executable ... ";
exec(shellCmd, function(error, stdout, stderr) {
if(error) {
console.log("Error running getting sid");
} else {
// get v1 and v2 from stdout
}
res.json( {"mystuff1":v1, "mystuff2":v2} );
});
app.post('/2setMyDiagValue', function(req, res)
{
// get the checkbox options from webpage,
// and save them in the backend
}
in the client side,
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.when('/5MyDiag', {
templateUrl: 'partials/MyDiag.html',
controller: 'MyDiagController'
});
}
]);
app.controller('myDiagController', function($scope, $http, $routeParams, QueryMyService) {
// using http.get() to get existing my setting from server side
QueryMyService.getInfoFromUrl7('/2getMyDiagValue').then(function(result) {
$scope.formData = result.formDataObjects;
}, function(error) {
alert("Error");
} );
$scope.submitForm = function() {
console.log("posting form data ...");
$http.post("/2setMyDiagValue",
JSON.stringify($scope.formData)).success(function(){} );
};
});
app.factory('QueryMyService', function($http, $q, $location) {
var factory = {};
var browserProtocol = 'http';
var address = 'localhost';
var server = browserProtocol + '://' + address;
//////////////////////////////////////////////////////////
factory.getInfoFromUrl7 = function(myUrl) {
var deferred = $q.defer();
$http.get(myUrl).success(function(data) {
deferred.resolve(data);
}).error(function(){
deferred.reject();
});
return deferred.promise;
}
return factory;
}
checkbox webpage itself: MyDiag.html
<form ng-submit="submitForm()" ng-controller="myDiagController">
<div class="control-group" style="color:black">
<label>My Checkbox</label>
<div class="checkbox">
<label class="checbox-inline" >
<input class="big-checkbox" type="checkbox" ng-model="formData.myStuff1"
ng-true-value="1" ng-false-value="0" ng-checked="formData.myStuff1 == 1">
<h4>Message 1</h4>
<input class="big-checkbox" type="checkbox" ng-model="formData.myStuff2"
ng-true-value="1" ng-false-value="0" ng-checked="formData.myStuff2 == 1">
<h4>Message 2</h4>
</label>
</div>
<br>
<input class="btn-primary" type="submit">
</form>
index.html
<div class="container">
<a class="btn btn-md btn-info custom-btn" ng-href="#/5MyDiag">Diagnostics</a>
</div>
Since i need to remove company names in the variable, there might be mismatch, but idea is the same. Thank you for your help.
Talked with guru, it's supposed to be so, if angular feels no change to the web GUI, e.g. in my case, i clicked the same button twice, it won't call the route provider again for the 2nd click.
If you knew this concept, you don't need to read my code to answer this question.
Wish i can get the 4 points back.

Why isn't updated model's value, updated via service, changing in UI?

Below, summary and test are set via MyCtrl. I'm seeing "my test" display properly, but not "summary.name". I'm seeing that MySvc.get()'s callback executes as expected, but summary.name's updated value doesn't appear on the UI.
Any suggestions on why summary.name's updated value isn't appearing on the UI ?
app.js:
...
.state('tab.edit', {
url: '/edit',
views: {
'tab-dash': {
templateUrl: 'templates/MyTemplate.html',
controller: 'MyCtrl'
}
}
})
...
MyTemplate.html:
<label class="item item-input item-stacked-label">
<span class="input-label">Name</span>
<textarea rows="8" placeholder="Nothing yet." ng-model="summary.name"></textarea>
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">TEST</span>
<textarea rows="8" placeholder="Nothing yet." ng-model="test"></textarea>
</label>
controllers.js:
...
.controller('MyCtrl', function($scope, MySvc) {
console.log("MyCtrl: entered");
$scope.summary = MySvc.get(0);
$scope.test = "my test";
...
MySvc.get(0) returns ( and I see this callback execute and change ret.name ):
return $http.get(url).then(function(response) {
console.log("MySvc callback: response.data = %o", response.data);
console.log("MySvc callback: response.data.name = " + response.data.name);
ret = new MySvc(response.data);
console.log("MySvc callback: ret.name = " + ret.name);
return ret;
});
You treated the return value of MySvc.get as a synchronous (immediately available) value. What is received via the $http service is not available immediately, so you can't treat it as a simple return value.
What you'll really want to do is use it as a promise, which it (most likely) is:
MySvc.get(0)
.then(function(summary) {
$scope.summary = summary;
});
And you'll probably want to read up on promises, Chapters 1 to 3 of "You Don't Know JS - Async & Performance" are an excellent starting point.

Resources