Creating an edit form - javascript

I am trying to create an edit from in my angularjs application but I am having some difficulty. I just do not know how to go about it.
This is the state that takes you to the form:
ui-sref="system.institutions.edit({ id: i.id })"
Now when the form loads I did this:
<form role="form" name="editInstitutionForm" ng-submit="editInstitution()" ng-init="getInstitutionInfo()">
...
</form>
The function getInstitutionInfo() is supposed to load the data from the server into the individual form fields.
This is the function:
$scope.getInstitutionInfo = function() {
InstService.show()
.success(function (data, status, headers, config) {
if (data.institutionInfo != undefined)
{
$scope.institutionInfo = data.institutionInfo;
}
})
};
This is the show method in my service:
InstService.show = function() {
var url = '/api/v1'+window.location.pathname;
url.replace('#', '');
return $http
.get(url)
};
Now my problem is how to pass the id from the state in the view through my controller to my http service.

Use $stateParams to access the id you are providing in the transition to the state here: ui-sref="system.institutions.edit({ id: i.id })"
Example:
.controller('InstEditCtrl', function ($scope, $state, $stateParams, InstService) {
var id = $stateParams.id;
});

Related

How to pass results from POST request to another page in Ionic and Angular

I'm using ionic to build a mobile app and I'm implementing very lightweight authentication (no security) into the app. Basically when a users hits the login button after submitting their email and password, their information is checked against a database using a POST request. Now my question is, once I have confirmed that the user's information is in the database, I'd like to pass that response object from the POST to a profile page that can then show the user's profile information. How can I pass information (the response object) from one controller to the another page so it can then be displayed on screen? Code below:
app.js
//Login view
.state('signin', {
url: '/signin',
templateUrl: 'templates/signin.html',
controller: 'LoginCtrl'
})
// Profile view:
.state('tab.profile', {
url: '/profile',
views: {
'tab-profile': {
templateUrl: 'templates/tab-profile.html'
controller: 'ProfileCtrl'
}
}
})
controllers.js:
$http.post(url, obj)
.success(function (res, status, headers, config) {
if (res == null){
console.log("bad login");
}
else{
// $scope.response = res;
console.log(res);
console.log("post successful");
$state.go('tab.profile',{response:res});
}
});
tab-profile.html
<ion-view view-title="Profile">
<ion-content>
<ion-list>
<ion-item >{{response.name}}</ion-item>
</ion-list>
</ion-content>
</ion-view>
You can create a service which will store data to be passed to other controllers.
Let me show an example:
var yourApp = angular.module('fooApp', []);
yourApp.factory('yourFactory', function() {
var items = [];
var storeService = {};
storeService.addItem = function(item) {
items.push(item);
};
storeService.removeItem = function(item) {
var index = items.indexOf(item);
items.splice(index, 1);
};
storeService.items = function() {
return items;
};
return storeService;
});
function MyCtrl($scope, yourFactory) {
$scope.newItem = {};
$scope.yourFactory = yourFactory;
}
You can define params in the definiton of a route. Look at the docu (https://github.com/angular-ui/ui-router/wiki/URL-Routing) of the ui-router module to see the right syntax.
In order to pass more complex object between two controllers i would use a service. Xou can set the data in the service after the POST is resolved and after the state change read it in the other controller. Read this link to see examples Passing data between controllers in Angular JS?. Hope this helps :)

Send POST request and get items in Angular

Im writing my first app with Angular and now faced up with the problem... I have address for POST request with authentication token. Something like:
http://example.com/orders?authentication_token=123456
So I need to make ng-submit or ng-click that send that request and get a bunch of items and show them on the page...
Also, I have a body for them:
{
"order": {
"seller_id":84,
"price":123,
"delivary_date":"12-12-2025",
}
}
So, what the best way to do that?
So you will have to make one angular service which would communicate with server and fetch the data and one angular controller which will interact with service to get the data and display over the UI.
Lets say service name is MyService:
app.service('MyService', function($http) {
var params = {}; // some parameters
this.getData = function(successCallback, failureCallback) {
$http.post("URL", params).then(function(data) {
successCallback(data);
}, function(data, status) {
failureCallback(data, status);
});
}
});
Controller name is MyCntrl:
app.controller('MyCntrl', function($scope, MyService) {
function successCallback(data) {
$scope.itemList = data;
}
function failureCallback(data, status) {
$scope.itemList = {};
}
$scope.handleClick = function() {
MyService.getData(successCallback, failureCallback);
}
});
I believe it would help you to resolve your requirement!!!
Assume you have a orderCtrl. ng-click or ng-submit is based on your app requirement. Call the function someFunction() that triggers $http post and you can handle the success and failure response.
app.controller('orderCtrl', function($scope, $http) {
$scope.someFunction = function(){
var data = {}; // prepare your data here.
$http({
method : "POST",
url : "specify your url here",
data : data
}).then(function mySucces(response) {
var response = response.data;
// handle your success here
}, function myError(response) {
// handle the failure here
});
});
});
Note :
If you are using a form and you want to trigger this function after user filling all the information, then use ng-submit. If it is independent then use ng-click.
I'm saying again, it's all depends on what you are doing.

angular how to set services in my case

I am trying to set http request data in one controller and let the data be used in multiple controller. I have something like
My services
angular.module('myApp').service('testService', ['Product','$q',
function(Product, $q) {
var products, targetProduct;
var deferred = $q.defer();
Product.query({
Id: 123
}, function(products) {
targetProduct = products[0];
deferred.resolve(products);
})
var getTargetProduct = function() {
var deferredtwo = $q.defer();
// return deferredtwo.promise;
deferred.promise.then(function(){
deferredtwo.resolve(targetProduct);
})
return deferredtwo.promise;
}
var setTargetProduct = function(targetProduct) {
targetProduct = targetProduct
}
return {
setTargetProduct: setTargetProduct,
getTargetProduct: getTargetProduct,
productPromise : deferred.promise
};
}
]);
nav controller
testService.productPromise.then(function(products){
$scope.products= products;
$scope.targetProduct = products[0];
})
//when user click the project ng-click = setTargetProduct(product);
$scope.setTargetProduct = function(targetProduct) {
testService.setTargetProduct(targetProduct)
}
product detail controller
testService.getTargetProduct().then(function(targetProduct) {
// works when page first loads
// but I don't know how to update the targetProduct when user select different
//targetProduct which means they trigger setTargetProduct() method
$scope.targetProduct = targetProduct;
})
As I stated above, I am not sure how to update the targetProduct in product detail controller when user pick another targetProduct. Can anyone help me about this? Thanks a lot!
As a matter of style, the function getTargetProduct doesn't need all this boilerplate code with promises. You want to return a simple promise wrapping your local data targetProduct. The function can be much cleaner :
var getTargetProduct = function() {
return $q.when(targetProduct);
}
Note: In the following, for convenience purpose, I will refer to your service testService by the name productService, and I will refer to your controller navController by the name ProductController
The controller NavController (gets the products as follows :
productService.getProducts().then(function(products) {
$scope.products = products;
}
When the user sets a target product (unchanged) :
$scope.setTargetProduct = function(targetProduct) {
testService.setTargetProduct(targetProduct)
}
Solution 1: nested controllers
If ProductDetailController is a nested controller of ProductController, the data targetProduct is shared without any logic from your part.
Solution 2: controllers not linked by a parent-child relationship
If the two controllers are not linked by a parent-child relationship, you can use $broadcast for broadcasting an updateTargetProduct event, and $on for handling that event.
In the controller from which we set the target product, we will find :
$rootScope.$broadcast('updateTargetProduct', targetProduct);
Note : $broadcast will broadcast the event from the rootscope down to the child scopes.
And in ProductDetailController, we will listen for this event :
$scope.$on('updateTargetProduct', function(event, data) {
// play with the received data
}
maybe your situation is not same as like me , but i made a service for my own $http call
var myService = angular.module('apix',[]);
myService.service('api',function( $http ){
this.http = function( method , path , data ){
return $http({
method: method,
url: path,
headers: {
'Content-Type' : 'application/x-www-form-urlencoded'
},
data : jQuery.param(data)
});
}
});
and used to call this as like
api.http('POST','your_path', data).success(function(result){ });
angular.module('myApp', [])
.factory('ipFactory', ['$http',
function($http) {
var service = {
getIp: function() {
return $http.get('http://ip.jsontest.com/', {
cache: true
})
.then(function(data) {
return data.data.ip;
});
}
}
return service;
}
])
.controller('ControllerOne', ['$scope', 'ipFactory',
function($scope, ipFactory) {
ipFactory.getIp()
.then(function(ip) {
$scope.ipAddress = ip;
});
}
])
.controller('ControllerTwo', ['$scope', 'ipFactory',
function($scope, ipFactory) {
ipFactory.getIp()
.then(function(ip) {
$scope.ipAddress = ip;
});
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="ControllerOne">
{{ipAddress}}
</div>
<div ng-controller="ControllerTwo">
{{ipAddress}}
</div>
</body>

AngularJS call common controller function from outside controller

My basic premise is I want to call back to the server to get the logged in user in case someone comes to the site and is still logged in. On the page I want to call this method. Since I am passing the user service to all my controllers I don't know which controller will be in use since I won't know what page they're landing on.
I have the following User Service
app.factory('userService', function ($window) {
var root = {};
root.get_current_user = function(http){
var config = {
params: {}
};
http.post("/api/user/show", null, config)
.success(function(data, status, headers, config) {
if(data.success == true) {
user = data.user;
show_authenticated();
}
});
};
return root;
});
Here is an empty controller I'm trying to inject the service into
app.controller('myResourcesController', function($scope, $http, userService) {
});
So on the top of my index file I want to have something along the lines of
controller.get_current_user();
This will be called from all the pages though so I'm not sure the syntax here. All examples I found related to calling a specific controller, and usually from within another controller. Perhaps this needs to go into my angularjs somewhere and not simply within a script tag on my index page.
You could run factory initialization in run method of your angular application.
https://docs.angularjs.org/guide/module#module-loading-dependencies
E.g.
app.run(['userService', function(userService) {
userService.get_current_user();
}]);
And userService factory should store authenticated user object internaly.
...
if (data.success == true) {
root.user = data.user;
}
...
Then you will be able to use your factory in any controller
app.controller('myController', ['userService', function(userService) {
//alert(userService.user);
}]);
You need to inject $http through the factory constructor function, for firsts
app.factory('userService', function ($window, $http) {
var root = {};
root.get_current_user = function(){
var config = {
params: {}
};
$http.post("/api/user/show", null, config)
.success(function(data, status, headers, config) {
if(data.success == true) {
user = data.user;
show_authenticated();
}
});
};
return root;
});
in your controller you can say
$scope.get_current_user = UserService.get_current_user();
ng attributes in your html if needed. besides this, i am not sure what you need.

AngularJS - $http POST with Rails 3.2.3

I'm building a simple Contact Management app with Crud using AngularJS 1.0.0rc8.
Getting a list of currently existing contacts is no problem, but while attempting to save a new Contact to the server, a new row is created - complete with the correct id, created_at, and updated_at values - but the rest of the models data is ignored.
Here is a screenshot to show what I mean:
As you can see, numbers 4 and 5 were given the Id's but first_name, last_name, and phone_num were not saved to the database.
I am using a $scope.addContact function within the Controller that deals with the object.
Here is the entire code for the Contact List Controller:
'use strict';
function ContactListCtrl($scope, $http) {
$http.get('/contacts').success(function(data) {
$scope.contacts = data;
});
$scope.addContact = function(data) {
$http.post('/contacts/', data).success(function(data) {
console.log(data);
data.first_name = $("#new_contact_first_name").val();
data.last_name = $("#new_contact_last_name").val();
});
this.newFirstName = '';
this.newLastName = '';
};
};
After clicking 'Save' on the new-contact.html partial, the Object is logged to the Console, if I inspect its contents, than sure enough the values are collected - notice Jimi Hendrix is there:
Here is the form as it appears in the new-contact.html template:
<form id="contact_form" ng-submit="addContact()">
<input type="text" id="new_contact_first_name" name="newContactFirstName" ng-model="newFirstName" placeholder="First Name"></br>
<input type="text" id="new_contact_last_name" name="newContactLastName" ng-model="newLastName" placeholder="Last Name"></br>
<input type="button" id="contact_submit_btn" value="Add Contact" class="btn btn-primary">
</form>
The addContact() function is fired after the form is submitted with JQuery:
$(document).ready(function(){
$("#contact_submit_btn").click(function(){
$("#contact_form").submit();
});
});
(Something tells me that I may not be using the ng-model attributes correctly.)
Any ideas on where I am going wrong with this? Or ideas on how I can better go about implementing this design?
Thanks.
UPDATE BELOW:
Here is my entire updated controller code - with help from Sathish:
// contacts controllers
'use strict';
function ContactListCtrl($scope, $http, Contacts) {
$scope.contacts = Contacts.index();
$scope.addContact = function() {
var newContact = {
first_name: $scope.newContactFirstName,
last_name: $scope.newContactLastName
};
var nc = new Contacts({ contact: newContact });
nc.$create(function() {
$scope.contacts.push(nc);
// now that the contact is saved, clear the form data
$scope.newContactFirstName = "";
$scope.newContactLastName = "";
})
}
};
ContactListCtrl.$inject = ['$scope', '$http', 'Contacts'];
function ContactDetailCtrl($scope, $routeParams, Contacts) {
$scope.contact = Contacts.get( {contact_id: $routeParams.contact_id} );
}
ContactDetailCtrl.$inject = ['$scope', '$routeParams', 'Contacts'];
I am now receiving the error: Unknown Provider for Contacts. Here is a screenshot of the error
Ok, I managed to fix that error by providing a ngResource to the main App file. Here's what it looks like:
// main app javascript file
'use strict';
angular.module('contactapp', ['ngResource']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/contacts', {template: 'assets/app/partials/contact-list.html', controller: ContactListCtrl}).
when('/contacts/new', {template: 'assets/app/partials/new-contact.html', controller: ContactListCtrl}).
when('/contacts/:contact_id', {template: 'assets/app/partials/contact-detail.html', controller: ContactDetailCtrl}).
otherwise({redirectTo: '/contacts'});
}]);
I am receiving a new error: WARNING: Can't verify CSRF token authenticity
Alright, managed to fix that problem too by adding a callback to the API controller:
Rails shows "WARNING: Can't verify CSRF token authenticity" from a RestKit POST
Now I am back to the original problem. When the create method is called, a new row is saved to the database, but the models data is not.
Awesome... finally got this thing working.
The problem was the $scope.addContact function. It was using the 'name' of the input instead of the ng-model binding called 'newFirstName' and 'newLastName' that resides in the template.
Here's what the updated function looks like:
$scope.addContact = function() {
var newContact = {
first_name: $scope.newFirstName,
last_name: $scope.newLastName
};
var nc = new Contacts({ contact: newContact });
nc.$create(function() {
$scope.contacts.push(nc);
// now that the contact is saved, clear the form data
$scope.newFirstName = "";
$scope.newLastName = "";
})
}
This can be better implemented using a Contacts service. Please define a Contacts service in app/assets/javascripts/services.js.erb as shown below:
var servicesModule = angular.module('<your app name>',
[<list of modules needed by this app>]);
servicesModule.factory('Contacts', function($resource) {
var ContactsService = $resource('/contacts/:contact_id', {}, {
'create': { method: 'POST' },
'index': { method: 'GET', isArray: true },
'update': { method: 'PUT' },
'destroy': { method: 'DELETE' }
});
return ContactsService;
});
Change the addContact method in the controller as shown below:
function ContactListCtrl($scope, $http, Contacts) {
...
...
...
$scope.addContact = function () {
var newContact = {
first_name: $scope.newContactFirstName,
last_name: $scope.newContactLastName
};
var nc = new Contacts({ contact: newContact });
nc.$create(function() {
$scope.contacts.push(nc);
// now that the contact is saved, clear the form data.
$scope.newContactFirstName = "";
$scope.newContactLastName = "";
});
};
...
...
...
}
ContactListCtrl.$inject = ['$scope', '$http', 'Contacts'];
In addition to this, you can simplify the $http.get(...) part also. You can use Contacts.index();
Note:
If you gave ng-app="MyAppName" then please replace <your app name> with MyAppName.
<list of modules needed by this app> needs to the replaced by a comma-separated list of strings representing any modules needed by your application.
Check the attr_accessible on your model. With new 3.2.3 rails all model attributes became protected from mass-assignment by default.

Categories

Resources