How to pass value from ng-click (AngularJS) to Laravel? - javascript

How to get value from ng-click and send to laravel for query?
//.html
<div ng-controller="recipientsController">
<div ng-repeat="recipient in recipients | orderBy:'-created_at'" ng-click="select(recipient.id)">
<p class="recipientname">{{ recipient.name }}</p>
</div>
</div>
//xxController.js
$scope.select = function() {
Comment.get()
.success(function(data) {
$scope.comments = data;
$scope.loading = false;
});
}
//xxService.js
get:function(){
var comments = $http.get('api/comments');
return comments;
},
//xxController.php [laravel]
public function index()
{
$comments = DB::table('c')
->join('u', 'c.id', '=', 'u.id')
->select('u.id', 'u.name', 'c.comments', 'c.created_at')
->where('u.id','=', Auth::user()->id)
->orWhere('u.id','=', **39 => this part has to be from ng-click value**)
->orderBy('c.created_at','asc')
->get();
return Response::json($comments);
}

You have passing the recipient.id parameter in your ng-click function but you did't retrieve the parameter in your js function
you need to retrieve the parameter
$scope.select = function(**id**) {
var selectedId=id;//you can check here
Comment.get()
.success(function(data) {
$scope.comments = data;
$scope.loading = false;
});
}

For passing data with $http.get method, there is second argument for [config] you can use that.
see: https://docs.angularjs.org/api/ng/service/$http#get for more reference about get method

Related

pass parameter from one controller to another page controller

.controller('ExplorerCtrl', ["$scope", "appServices","$location", 'appSettings', function ($scope, appServices, $location, appSettings) {
$scope.changeLocation = function() {
$location.path('career'?name={{career.Name}});
};
$scope.getCareerList = function(){
appServices.doAPIRequest(appSettings.appAPI.career.overviewList, null, null).then(function(data){
$scope.allCareer = data.data.n;
})
};
How to pass parameter from one controller to another page controller. the career.name I want to b appended in my next page API.

Unable to filter data from knockout view model with drop down selection change

I have a simple controller like this:
public JsonResult GetPosts(int? id)
{
var varid = id;
var ret = (from post in db.Posts.ToList()
orderby post.PostedDate descending
select new
{
NeighbourhoodId = varid,
Message = post.Message,
PostedByName = post.ApplicationUser.UserName,
PostedDate = post.PostedDate.ToString(),
PostId = post.PostId,
});
return Json(ret, JsonRequestBehavior.AllowGet);
}
Here, i am able to get the dropdown selected value.I am assigning it to a variable varid and then assigning it to NeighbourhoodId.
But, when the view page is rendered nothing changes all the 4 Post are showing.but in reality it should display only 2 Post.
This is my view page code:
<ul id="msgHolder" data-bind="foreach: posts">
<li class="postHolder">
<p><a data-bind="text: PostedByName"></a>: <span data-bind=" html: Message"></span></p>
and my wallpost.js file in script folder where all knockout view model related code is here.It first loads all the Post from database correctly but data doesnot get filtered if i am trying to filter it with dropdown change.
function Post(data) {
var self = this;
data = data || {};
self.PostId = data.PostId;
self.NeighbourhoodId = data.NeighbourhoodId;
self.Message = ko.observable(data.Message || "");
self.PostedByName = data.PostedByName || "";
self.PostedDate = getTimeAgo(data.PostedDate);
self.error = ko.observable();
function viewModel() {
var self = this;
self.posts = ko.observableArray();
self.newMessage = ko.observable();
self.error = ko.observable();
self.loadPosts = function () {
// to load existing posts
$.ajax({
url: postApiUrl,
datatype: "json",
contentType: "application/json",
cache: false,
type: 'Get'
})
.done(function (data) {
var mappedPosts = $.map(data, function (item)
{ return new Post(item); });
self.posts(mappedPosts);
})
.fail(function () {
error('unable to load posts');
});
}
return self;
};
ko.applyBindings(new viewModel());
and my dropdown related code is here:
#Html.DropDownList("Locations", ViewBag.NeighbourhoodId as SelectList,"Select a Location")
<script type="text/javascript">
$(document).ready(function () {
$("#Locations").change(function () {
var locationSelected = $("#Locations").val();
var url = '#Url.Action("GetPosts", "Post")';
$.post(url, { id: locationSelected },
function (data) {
});
});
});
</script>
When i debug, i am getting correct id value in controller but there is problem in filtering out data. Is there a need for some change in knockout file.what to do here ??
Instead of mixing jquery event handlers and knockout bindings, i think it's better for you handle all with knockout.
Bind your select element (drop down) with the options binding and load the locations array on view model initialization; bind the value to a observable property, ex: 'CurrentLocation'
Subscribe to the change of the property 'CurrentLocation', ex:
myViewModel.CurrentLocation.subscribe(function(newValue) {
//request to GetPosts here
});
On .done() function of the GetPosts request update the observableArray with the items received by the server
Hope this helps!
UPDATE
The following is a very simple example, i changed my mind and used "event" binding to handle the change event instead of "options" binding but the concept it's the same.
#Html.DropDownList("Locations", new SelectList(Model.Locations, "Id", "Name"), new { data_bind = "event: { change: reloadPosts}" })
<ul data-bind="foreach: posts">
<li data-bind="text:CompleteText"></li>
</ul>
<script>
function Post(data) {
var self = this;
self.Id = ko.observable(data.Id);
self.LocationId = ko.observable(data.LocationId);
self.Text = ko.observable(data.Text);
self.CompleteText = ko.computed(function () {
return self.Id() + " " + self.Text();
});
}
function PageViewModel() {
var self = this;
self.posts = ko.observableArray();
self.reloadPosts = function () {
$.ajax({
type:"POST",
url: "GetPosts",
data: { locationId: $("#Locations").val() }
}).done(function (data) {
var mappedPosts = $.map(data, function (item)
{ return new Post(item); });
self.posts(mappedPosts);
});
}
}
var vm = new PageViewModel();
ko.applyBindings(vm);
</script>
The GetPosts method in the controller:
[HttpPost]
public JsonResult GetPosts(string locationId)
{
var selectedPosts = posts.Where(x => x.LocationId == locationId);
return Json(selectedPosts, JsonRequestBehavior.AllowGet);
}
The posts collection in the controller in the example above it's just an inmemory collection, probably you will read it from a DB or something like that.
The post class on the c# code:
class Post
{
public string Id { get; set; }
public string LocationId { get; set; }
public string Text { get; set; }
}
And finally the viewmodel used:
public class TestViewModel
{
public List<Location> Locations { get; set; }
}

Angular Controller Loading Before Data Is Loaded

I am writing a simple app that loads movie info from an API. After this loading, I am attempting to use Angular to display the movies in a simple list view. I am correctly loading the movies, but it seems like the angular controller is created and sends the movie array to the view before the movie array is populated. I am unsure how to get around this.
var movieList = [];
var app = angular.module('top250', []);
// immediately make a call to the server to get data (array of movies from text file)
$.post('/', {}, function(data) {
init(data);
});
app.controller('MovieController', function() {
// should be setting this.movies to an array of 250 movies
this.movies = movieList;
});
function init(data) {
// cycle through array, use title to retrieve movie object, add to array to be sent to view
$.each(data, function(index, value) {
var title = value.split(' (')[0];
title = title.split(' ').join('+');
var url = 'http://www.omdbapi.com/?t=' + title + '&y=&plot=short&r=json';
$.getJSON(url, function(data) {
console.log('in get json', data);
var movieObj = data;
storeMovie(movieObj);
});
});
}
function storeMovie(movieObj) {
movieList.push(movieObj);
}
And my HTML (although I'm certain this isn't the problem:
<body ng-controller="MovieController as MovieDB">
<div class="row">
<div class="large-12 columns">
<h1>IMDB Top 250 List</h1>
</div>
</div>
<div class="row">
<div class="large-12 columns" id="movie-list">
<div class="list-group-item" ng-repeat="movie in MovieDB.movies">
<h3>{{movie.Title}} <em class="pull-right">{{movie.Plot}}</em></h3>
</div>
</div>
<script src="js/foundation.min.js"></script>
<script>
$(document).foundation();
</script>
</body>
First I transformed your ajax calls to an angular factory:
app.factory('MoviesService', function($http, $q) {
function getMovie(value) {
var title = value.split(' (')[0];
title = title.split(' ').join('+');
var url = 'http://www.omdbapi.com/?t=' + title + '&y=&plot=short&r=json';
return $http.get(url).then(function(res){ return res.data; });
}
return $http.post('/').then(function(res) {
return $q.all(res.data.map(getMovie));
});
});
Then I can consume it like so:
app.controller('MovieController', function(MoviesService) {
var self = this;
MoviesService.then(function(movies) {
self.movies = movies;
});
});
don't use jquery
use angular $http or $resource
using $http, you set scope var to the data inside promise, and life will be good
You need to wait for you init method to complete:
function init(data, complete) {
$.each(data, function(index, value) {
var title = value.split(' (')[0];
title = title.split(' ').join('+');
var url = 'http://www.omdbapi.com/?t=' + title + '&y=&plot=short&r=json';
$.getJSON(url, function(data) {
console.log('in get json', data);
var movieObj = data;
storeMovie(movieObj);
}).always(function(){ // count competed ajax calls,
// regardless if they succeed or fail
if(index === data.length -1)
complete(); // call callback when all calls are done
});
});
}
Now you can do this:
app.controller('MovieController', function() {
$.post('/', {}, function(data) {
init(data, function(){
this.movies = movieList;
});
});
});
Personally I would just keep the movieList inside of the init method and send it with the callback when you're done, but that's just a preference.

Passing data from Service AngularJS

Dear all I am having trouble with the scope of my $scope or how should I put it.
I am retrieving the data from my Service successfully but I´m having trouble with accessing $scope.players and $scope.tournament and I think it has something to do with being inside the service call. If I console.out() inside the service call everything is just fine. How can I be able access the data which is inside of the service call.
Version 1:
Here console log simply states undefined.
.controller('SelectCtrl', ['$scope','$stateParams', '$location', '$window','playerService','tournamentService', function ($scope, $stateParams, $location, $window, playerService, tournamentService) {
init();
function init() {
playerService.getPlayers().then(function (data) {
$scope.players = [];
angular.forEach(data, function (player, index) {
$scope.players.push(player.info);
});
});
tournamentService.getTournaments().then(function (data) {
var result = data.filter(function (element) {
if (element.ID == $stateParams.id) {
return true;
} else {
return false;
}
});
$scope.tournament = result;
});
};
console.log($scope.tournament);//undefined
console.log($scope.players); //undefined
}
Version 2:,
Here console log simply states the Object {then: function, catch: function, finally: function} Which is not what I wan´t I want the data to be able to display it in my view.
.controller('SelectCtrl', ['$scope','$stateParams', '$location', '$window','playerService','tournamentService', function ($scope, $stateParams, $location, $window, playerService, tournamentService) {
init();
function init() {
$scope.players = playerService.getPlayers().then(function (data) {
$scope.players = [];
angular.forEach(data, function (player, index) {
$scope.players.push(player.info);
});
});
$scope.tournament = tournamentService.getTournaments().then(function (data) {
var result = data.filter(function (element) {
if (element.ID == $stateParams.id) {
return true;
} else {
return false;
}
});
$scope.tournament = result;
});
};
console.log($scope.tournament);//Object {then: function, catch: function, finally: function}
console.log($scope.players);//Object {then: function, catch: function, finally: function}
}
Your help is really appreciated!
The Services:
.factory('playerService', function ($http,$q) {
return {
getPlayers: function () {
//return the promise directly.
var deferred = $q.defer();
$http.get(webServiceUrl + 'api/Player/GetAllPlayers')
.success(function (data) {
//resolve the promise as the data
deferred.resolve(data);
}).error(function () {
deferred.reject();
});
return deferred.promise;
}
}
})
.factory('tournamentService', function ($http,$q) {
return {
getTournaments: function () {
//return the promise directly.
var deferred = $q.defer();
$http.get(webServiceUrl + 'api/Tournament/GetAllTournaments')
.success(function (data) {
//resolve the promise as the data
deferred.resolve(data);
}).error(function () {
deferred.reject();
});
return deferred.promise;
}
}
})
Part of the view:
<h1 style="display: inline-block; margin-left:15px;">Enter <i>{{tournament.Name}}</i></h1>
<div class="row">
<div class="selectinforow">
<div class="col-xs-2 selectinfo">
<span>{{tournament.EntryFee}}$</span></br>
<span>Entry Fee</span>
</div>
<div class="col-xs-2 selectinfo">
<span>{{tournament.Entries}}</span></br>
<span>Entries</span>
</div>
<div class="col-xs-2 selectinfo">
<span>{{tournament.Size}}</span></br>
<span>Max Size</span>
</div>
<div class="col-xs-2 selectinfo">
<span>{{tournament.StartTime}}</span></br>
<span>Start Date</span>
</div>
<div class="col-xs-2 selectinfo">
<span>{{tournament.Entryfee*tournament.Entries}}$</span></br>
<span>Winnings</span>
</div>
</div>
</div>
So if you read your code carefully you will notice you are using a promise on the following line:
tournamentService.getTournaments().then(function (data) {
// [your data is set here - AFTER the service call runs]
}
// [your print is here - run BEFORE service call runs]
The key to the "then" statement is it isn't executed right away, but is instead run when data is returned from the service call. In other words, you have your print in the wrong spot - I would expect the values to be undefined there. If you move the console.log statements into the promise (then) - I would expect to see the valid values. You can also put a break point in the browser debugger to see the values in the "then" function if you want to validate that things are working. Hope this puts you on the right track!
EDIT
Once the promise completes, angular automatically updates the view. Lets say you have the following in your view (just an example):
<h1 ng-bind="tournament.Title">Default Text</h1>
When the view/page loads you will see "Default Text". After the promise completes, if a tournament has been loaded, angular will automatically update the "h1" to now have the Title for that tournament. This happens because angular automatically runs an "$apply()" after a promise completes.
Your code is executed before the promise response.
If you need to code "procedurally", you should $watch the scope variable as below to detect any changes.
For example:
$scope.$watch('tournament', function() {
console.log($scope.tournament);
}, true);

ng-class only for current scope in ng-repeat angularjs

I'm having trouble with the ng-class part of AngularJS.
The only thing I figured out was adding the class after a success or error to allll buttons where the ng-click was on.
But I only want to add/change the class of the currently clicked element. Is that even possible in a way?
<section ng-repeat="user in users">
<button class="btn" ng-click="myFunction(user);" ng-class="{invalid:errors,done:success}"></button>
</section>
<script>
function UsersController($scope, $http) {
$http.get('/users.json').success(function(users) {
$scope.users = users;
$scope.errors = false;
$scope.success = false;
});
$scope.myFunction = function(user) {
$http.post('/myUrl/'+user.id, student)
.success(function(data, status, headers, config) {
// $scope.success = true;
user.success = true;
})
.error(function(data, status, headers, config) {
// $scope.errors = true;
user.errors = true;
});
}
}
</script>
What I want is just the current scope, but that doesn't work.
My function does work, except for passing the ng-class values trough.
Another solution:
<section ng-repeat="user in users">
<button class="btn" ng-click="myFunction(user)"
ng-class="{invalid: isInvalid(user), done: isSuccess(user)}">{{user.name}}</button>
</section>
So you create isInvalid and isSuccess functions and pass in current user object:
$scope.isSuccess = function(user) {
return user === $scope.state.success;
};
$scope.isInvalid = function(user) {
return user === $scope.state.errors;
};
These two functions can decide if current user is invalid or successful. For example when there is an error you set it like this:
$scope.state = {
success: false,
errors: user
};
Demo: http://plnkr.co/edit/RDJy9VsRkhAO0cFnb6AV?p=preview
Have a property on the scope to represent the current user and a test for it in the ng-class expression:
$scope.currentUser = null;
$scope.myFunction = function(user) {
$http.post('/myUrl/'+user.id, student)
.success(function(data, status, headers, config) {
$scope.currentUser = user;
user.success = true;
})
.error(function(data, status, headers, config) {
user.errors = true;
});
};
ng-class="{invalid:user.errors && currentUser == user,done:user.success && currentUser == user}"
Instead of attaching the function myFunction to the $scope, you want to attach it to each user as such...
for(var i=0;i<users.length;i++){
users[i].myFunction= function(id){...}
}
and then for your ng-class you do.
ng-class={invalid: user.errors, done:user.success}

Categories

Resources