POST data to server using AngularJS (ionic framework) - angularjs

I'm trying to post data to a server from my ionic app. The URL to use is in a variable. Here is what I tried:
First I've created a service like this:
.service('PostTuto', ['$http',function($http) {
this.servicioPostTuto = function(tema,ubicacion,horario,nom_coe) {
return $http({
method: 'POST',
url: 'http://"""""".""".""""."""":8080/smartlandiotv2/webresources/entidades.datos/insert?apikey=3bff8615827f32442199fdb2ed4df4&trama={"Nombre":"'+tema+'","Apellido":"'+ubicacion+'","Sexo":"'+horario+'","Residencia":"'+nom_coe+'"}',
});
};
}])
in this part I send in my url the variables tema, ubicacion, horario, nom_coe and my controller. I've done this:
$scope.data = {};
$scope.create=function(){
$scope.nom_coe="IDfromSubject"
PostTuto.servicioPostTuto($scope.data.tema,$scope.data.ubicacion,$scope.data.horario,$scope.nom_coe)
.success(function(data){
var alertPopup = $ionicPopup.alert({
title: 'created'
});
})
.error(function(data){
var alertPopup = $ionicPopup.alert({
title: 'Error to post data'
});
});
};
//FIN POSTEAR DATOS A SERVIDOR
In this part I receive the data from input in my html file.
<label class="item item-input item-stacked-label">
<span class="input-label"><strong>Tema:</strong></span>
<input type="text" ng-model="data.tema" ng-disabled="editar">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label"><strong>Ubicacion:</strong></span>
<input type="text" ng-model="data.ubicacion" ng-disabled="editar">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label"><strong>Horario:</strong></span>
<input type="text" ng-model="data.horario" ng-disabled="editar">
</label>
<a class="button button-block icon-left ion-ios-compose button-positive"
ng-disabled="!data.tema || !data.ubicacion || !data.horario" ng-click="create()">
create
</a>
When I try to post data, my app returns me an error "Error to post data", how can I fix that?

Sending your API key in querystring is not a good way.You could try this
In Controller Js
$scope.data=new Object();
$scope.create=function(){
PostTuto.servicioPostTuto($scope.data)
.success(function(data){
var alertPopup = $ionicPopup.alert({
title: 'created'
});
})
.error(function(data){
var alertPopup = $ionicPopup.alert({
title: 'Error to post data'
});
});
};
And in your AppConfig.js
app.run(function($http){
$http.defaults.headers.common['APIKey'] = "3bff8615827f32442199fdb2ed4df4";
})
And in your service
.service('PostTuto', ['$http',function($http) {
this.servicioPostTuto = function(data) {
return $http.post('http://"""""".""".""""."""":8080/smartlandiotv2/webresources/entidades.datos/insert',data);
}
}])
Now from serverside ,you could get your APIKey from Request header for your purpose

Related

How to clear input field on button click in Ionic 1

I am new to Ionic 1. The problem is click on Submit button the input fields doesn't clear. On button click after posting data to server it reloads the same page but with already entered fields.
html
<div style="margin-left: 20px;margin-right: 20px;margin-top: 55px;">
<div class = "list">
<label class = "item item-input item-stacked-label">
<!-- <span class = "input-label">Name</span> -->
<input type = "text" placeholder = "Name" required ng-model="name" clearInput="true"/>
</label>
</div>
<div class = "list">
<label class = "item item-input item-stacked-label">
<!-- <span class = "input-label">Mobile Number</span> -->
<input type = "tel"maxlength="10" clearInput="true" placeholder = "Mobile No." pattern="[1-9]{1}[0-9]{9}" required ng-model="mobile" />
</label>
</div>
<div class="padding text-right" style="margin-top: -12px;">
<button class="button button-positive " ng-click="enter(name,mobile)" style="width: 100%;">
Submit
</button>
</div>
</div>
js
$scope.enter = function (name,mobile) {
if (name == null) {
var alertPopup = $ionicPopup.alert({
template: 'Please Enter Name!'
});
} else if (mobile == null) {
var alertPopup = $ionicPopup.alert({
template: 'Please Enter Mobile Number!'
});
}
else {
$ionicLoading.show({
template: '<ion-spinner></ion-spinner><p>Loading...</p>'
});
var link = 'http://mountsystem/mobileapi/coreapi.php';
var datasend = $.param({
request_code: 'demo_attendance',
batch_id:$stateParams.batchId,
mobile_no: mobile,
student_name: name,
franchise_id: $scope.userDetails.franchise_id,
entered_by:$scope.userDetails.employee_id
});
console.log(datasend);
$http.post(link, datasend, config)
.success(function (response) {
$ionicLoading.hide();
console.log(response);
if (response.response_code == 'STATUS_OK') {
$scope.list = response;
console.log($scope.list);
var alertPopup = $ionicPopup.alert({
title: 'Hurrayy',
content: 'Successfully Submitted !'
})
} else {
var alertPopup = $ionicPopup.alert({
title: 'Error!',
template: response.msg
});
}
}).error(function (response) {
$ionicLoading.hide();
var alertPopup = $ionicPopup.alert({
title: 'ServerError!',
template: 'ServerError' + response
});
});
}}
I just want as soon as I click submit button both input fields (username and mobile number) will be clear so that I again entered new details.
Try to set the name and telephone variables to "" in your .js file. It will clear the fields in the front.
Also why are you still using Ionic 1. I recommend moving to Ionic 3, waiting the fourth version to be really stable.
Change ng-model variable with below code
<div style="margin-left: 20px;margin-right: 20px;margin-top: 55px;">
<div class = "list">
<label class = "item item-input item-stacked-label">
<!-- <span class = "input-label">Name</span> -->
<input type = "text" placeholder = "Name" required ng-model="data.name" clearInput="true"/>
</label>
</div>
<div class = "list">
<label class = "item item-input item-stacked-label">
<!-- <span class = "input-label">Mobile Number</span> -->
<input type = "tel"maxlength="10" clearInput="true" placeholder = "Mobile No." pattern="[1-9]{1}[0-9]{9}" required ng-model="data.mobile" />
</label>
</div>
<div class="padding text-right" style="margin-top: -12px;">
<button class="button button-positive " ng-click="enter(data.name,data.mobile)" style="width: 100%;">
Submit
</button>
</div>
</div>
$scope.data = {};
$scope.enter = function (name,mobile) {
if (name == null) {
var alertPopup = $ionicPopup.alert({
template: 'Please Enter Name!'
});
} else if (mobile == null) {
var alertPopup = $ionicPopup.alert({
template: 'Please Enter Mobile Number!'
});
}
else {
$ionicLoading.show({
template: '<ion-spinner></ion-spinner><p>Loading...</p>'
});
var link = 'http://mountsystem/mobileapi/coreapi.php';
var datasend = $.param({
request_code: 'demo_attendance',
batch_id:$stateParams.batchId,
mobile_no: mobile,
student_name: name,
franchise_id: $scope.userDetails.franchise_id,
entered_by:$scope.userDetails.employee_id
});
console.log(datasend);
$http.post(link, datasend, config)
.success(function (response) {
$ionicLoading.hide();
console.log(response);
if (response.response_code == 'STATUS_OK') {
$scope.list = response;
console.log($scope.list);
$scope.data.mobile = '';
$scope.data.name = '';
var alertPopup = $ionicPopup.alert({
title: 'Hurrayy',
content: 'Successfully Submitted !'
})
} else {
var alertPopup = $ionicPopup.alert({
title: 'Error!',
template: response.msg
});
}
}).error(function (response) {
$ionicLoading.hide();
var alertPopup = $ionicPopup.alert({
title: 'ServerError!',
template: 'ServerError' + response
});
});
}}
I am quite amazed with the solution but this solution worked for me, the problem was instead of setting a value directly inside $scope object, I was supposed to put it within any object of $scope object like this
<input type="text" placeholder="Enter new todo" ng-model="data.newtodo"> first change model of input field to like this
and in my controller, on top
$scope.data = {};
and after success callback
$scope.data.newtodo = "";

Angular contact form - undefined field after after sending

Here is my index.html
<div data-ng-controller="help">
<div id="messages" class="alert alert-success" data-ng-show="messages" data-ng-bind="messages"></div>
<div data-ng-show="progress.active()" style="color: red; font-size: 50px;">Sending…</div>
<form name="helpForm" novalidate role="form">
<div class="form-group">
<label for="name">Your Name </label>
<span class="label label-danger" data-ng-show="submitted && helpForm.name.$error.required">Required!</span>
<input type="text" name="name" data-ng-model="userName" class="form-control" required />
</div>
<div class="form-group">
<label for="email">Your E-mail address</label>
<span class="label label-danger" data-ng-show="submitted && helpForm.email.$error.required">Required!</span>
<span class="label label-danger" data-ng-show="submitted && helpForm.$error.email">Invalid email!</span>
<input type="email" name="email" data-ng-model="userEmail" class="form-control" required />
</div>
<div class="form-group">
<label for="message">Message</label>
<span class="label label-danger" data-ng-show="submitted && helpForm.message.$error.required">Required!</span>
<textarea name="message" data-ng-model="userMessage" class="form-control" required></textarea>
</div>
<button data-ng-disabled="progress.active()" data-ng-click="submit(helpForm)" class="btn btn-default">Submit</button>
</form>
And part of my app.js
angular.module('myApp', ['ajoslin.promise-tracker'])
.controller('help', function ($scope, $http, $log, promiseTracker, $timeout) {
$scope.subjectListOptions = {
'bug': 'Report a Bug',
'account': 'Account Problems',
'mobile': 'Mobile',
'user': 'Report a Malicious User',
'other': 'Other'
};
$scope.progress = promiseTracker();
$scope.submit = function(form) {
$scope.submitted = true;
if (form.$invalid) {
return;
}
var $promise = $http({
method: 'POST',
url:'api/contactUs',
params: {
'callback' : 'JSON_CALLBACK',
'userName' : $scope.userName,
'userEmail' : $scope.userEmail,
'userMessage' : $scope.userMessage
}
})
.success(function(data, status, headers) {
if (data.status == 'OK') {
$scope.userName = null;
$scope.userEmail = null;
$scope.userMessage = null;
$scope.messages = 'Your form has been sent!';
$scope.submitted = false;
} else {
$scope.messages = 'Oops, we received your request, but there was an error processing it.';
$log.error(data);
}
})
.error(function(data, status, headers) {
$scope.progress = data;
$scope.messages = 'There was a network error. Try again later.';
$log.error(data);
})
.finally(function() {
$timeout(function() {
$scope.messages = null;
}, 9000);
});
After sending the letter to mail, all fields (name, email, message) in the form are displayed as "Undefined"
I use an node.js server and connect via api (api/contactUs)
I can not understand what the problem is, already tried everything I could, but the error remains.
Please help with the solution of this problem.
Thank you in advance!
When you use POST method, you should pass data object instead of params object.
Change this:
params: {
'callback' : 'JSON_CALLBACK',
'userName' : $scope.userName,
'userEmail' : $scope.userEmail,
'userMessage' : $scope.userMessage
}
To this:
data: {
'callback' : 'JSON_CALLBACK',
'userName' : $scope.userName,
'userEmail' : $scope.userEmail,
'userMessage' : $scope.userMessage
}

angularjs $http: server 500 (Internal Server Error) when working with laravel

I have searched many solutions but still cannot work.
it shows me
POST http://localhost/travelAbroad/public/touristsData 500 (Internal Server Error)
what i wanna do is that when i choose the filters, the will change according to the filters you choose. And i use ionic as a frontend framework to make a html5 mobile application.
The following is my code:
//html
<span class="ion-ios-arrow-down button button-icon" ng-click="modal.show()"></span>
...
<ion-list>
<ion-item ng-repeat="tourist in tourists | limitTo:numberOfItemsToDisplay">
<h3>Charge: $#{{tourist.charge}}/h</h3>
</ion-item>
</ion-list>
//filterModal file
<ion-modal-view>
<ion-content>
<form name="filterForm" ng-submit="submitForm()">
<div class="list">
<ion-radio ng-model="filter.want" value="company" name="want">
Want a company for building a house
</ion-radio>
<ion-radio ng-model="filter.want" value="expat" name="want">
Find an expaters
</ion-radio>
<div class="list">
<label class="item item-input item-select">
<select ng-model="filter.location" name="location">
<option value="Xihu" selected>Xihu</option>
<option value="Xiacheng">Xiacheng</option>
</select>
</label>
</div>
<input type="hidden" ng-model="filter.token" name="token" value="{{ csrf_token() }}">
<input type="submit" class="button button-full button-light" value="Create">
</div>
</ion-content>
</ion-modal-view>
//angular controller
.controller('listController', ['$scope','$http','$state','$ionicModal', function($scope, $http, $state,$ionicModal){
$http.get("./touristsData").success(
function(data){
$scope.tourists = data;
$scope.numberOfItemsToDisplay = 3; // number of item to load each time
$scope.addMoreItems = function(){
if($scope.tourists.length>$scope.numberOfItemsToDisplay){
$scope.numberOfItemsToDisplay += 3; // load 20 more items
}
............
});//end of get method
$ionicModal.fromTemplateUrl('./filterModal', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.filter = {};
$scope.submitForm = function(){
if($scope.filter.want == 'company'){
$http({
method : 'POST',
url : './touristsData',
beforeSend: function (xhr) {
var token = $scope.filter.token;
if (token) {
return xhr.setRequestHeader('X-CSRF-TOKEN', token);
}
},
data : {
location: $scope.filter.location
},
headers : {'Content-Type': 'application/x-www-form-urlencoded'}
})
.success(function(data){
$scope.tourists = data;
});
$scope.modal.hide();
}
}
//backend
//laravel route:
Route::match(array('GET', 'POST'), '/touristsData', array(
'uses' => 'UserController#touristsData',
'as' => 'touristsData'
));
//laravel controller:
public function touristsData(){//get
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
//$postdata = json_decode(file_get_contents('php://input'));
if(isset($request->location)){
#$location = $request->location;
$tourists = User::where('block','0')
->where('location', $location)
->orderBy('updated_at', 'desc')
->get();
}else{
$tourists = User::where('block','0')
->orderBy('updated_at', 'desc')
->get();
}
//$touristsPostInfo = Post::where('block','0')->get();
return View::make('frontend.data.touristsData',array('tourists'=>$tourists));
}
//touristsData
echo json_encode($tourists);
Include this in your header:
<meta id="token" name="token" content="{{ csrf_token() }}">
This kind of error is captured on the error log file of your server,
you can login with FTP and get the error.log file to check exactly the line and what is the problem.
$http: server 500 (Internal Server Error)
You're server is expecting a url encoded string and you are sending through an object thus it throws the error.
Update following
data: {
location: $scope.filter.location
}
To
data : $httpParamSerializer({
location: $scope.filter.location
})
You'll need to inject the $httpParamSerializer function.

MEAN stack ng-upload-file

I am currently using MEAN.js to create an app and I scaffolded a simple entity called Campaign. I would like each Campaign to have a picture associated. Therefore, I would like to change the CRUD interface to be able to upload a file to the back end.
I injected the ng-file-upload plugin to create the FE with Angular. On the Node.js side, I installed the multer plugin to help me save the file into a folder (e.g. ./uploads). The thing is that I do not quite get the flow and I was hoping for a suggestion.
Please, find below the view:
<section data-ng-controller="CampaignsController">
<div class="page-header">
<h1>New Campaign</h1>
</div>
<div class="col-md-12">
<form class="form-horizontal" data-ng-submit="create()" novalidate>
<fieldset>
<div class="form-group">
<label class="control-label" for="name">Name</label>
<div class="controls">
<input type="text" data-ng-model="name" id="name" class="form-control" placeholder="Name" required>
</div>
</div>
<div class="form-group">
<button ng-file-select ng-model="token">Upload the token</button>
<div ng-file-drop ng-model="token" class="drop-box"
drag-over-class="{accept:'dragover', reject:'dragover-err', delay:100}"
accept="image/*">
Drop image file here
</div>
<div ng-no-file-drop>Image drop is not supported for this browser.</div>
</div>
<div class="form-group">
<input type="submit" class="btn btn-default">
</div>
<div data-ng-show="error" class="text-danger">
<strong data-ng-bind="error"></strong>
</div>
</fieldset>
</form>
</div>
</section>
Then, the Angular controller action:
// Create new Campaign
$scope.create = function() {
// Create new Campaign object
var campaign = new Campaigns ({
name: this.name
});
$scope.$watch('token', function() {
$scope.upload = $upload.upload({
url: '/campaigns', //upload.php script, node.js route, or servlet url
method: 'POST', //Post or Put
headers: {'Content-Type': 'multipart/form-data'},
//withCredentials: true,
data: campaign, //from data to send along with the file
file: $scope.token, // or list of files ($files) for html5 only
//fileName: 'photo' // to modify the name of the file(s)
}).success(function (response, status) {
// Redirect after save
campaign.$save(function(response) {
$location.path('campaigns/' + response._id);
// Clear form fields
$scope.name = '';
}, function(errorResponse) {
$scope.error = errorResponse.data.message;
});
}
).error(function (errorResponse) {
$scope.error = errorResponse.data;
//$scope.error = errorResponse.data.message;
});
});
};
Finally, the Node.js controller portion:
var mongoose = require('mongoose'),
errorHandler = require('./errors'),
multer = require('multer'),
Campaign = mongoose.model('Campaign'),
_ = require('lodash');
/**
* Create a Campaign
*/
exports.create = function(req, res) {
var campaign = new Campaign(req.body);
campaign.user = req.user;
multer({
dest: './uploads/'
});
campaign.save(function(err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.jsonp(campaign);
}
});
};
Right now, what happens is that - when I try to upload a file - the uploader does not wait for the file to be selected, but it sends the POST request immediately (why?). Moreover, I get a 400 response.
Any suggestion would be really appreciated!
Thanks
Cheers
I partially solved the problem.
This is the new view:
<section data-ng-controller="CampaignsController">
<div class="container">
<div class="page-header">
<h1>New Campaign</h1>
</div>
<div class="col-sm-12 col-md-4 col-md-offset-4">
<form class="form-horizontal" data-ng-submit="create(token)" novalidate>
<fieldset>
<div class="form-group">
<label class="control-label" for="name">Name</label>
<div class="controls">
<input type="text" data-ng-model="name" id="name" class="form-control" placeholder="Name" required>
</div>
</div>
<div class="form-group">
<label class="control-label" for="token">Token</label>
<div class="controls">
<input type="file" id="token" ng-file-select ng-model="token"/>
<p class="help-block">The token file must be a squared .png or .jpg image.</p>
</div>
</div>
<div class="form-group">
<div class="controls">
<input type="submit" class="btn btn-default col-xs-12">
</div>
</div>
<div class="form-group">
<div data-ng-show="error" class="control alert alert-danger alert-dismissible" role="alert">
<span data-ng-bind="error"></span>
</div>
</div>
</fieldset>
</form>
</div>
</div>
</section>
Then, the Angular controller action:
$scope.create = function(token) {
// Create new Campaign object
var campaign = new Campaigns ({
name: this.name
});
$scope.upload = $upload.upload({
url: '/campaigns',
method: 'POST',
headers: {'Content-Type': 'multipart/form-data'},
//withCredentials: true,
data: {
campaign: JSON.stringify(campaign)
},
file: token,
//fileName: 'token' // to modify the name of the file
}).success(function (response, status) {
// Redirect after save
$location.path('campaigns/' + response._id);
// Clear form fields
$scope.name = '';
$scope.token = '';
}
).error(function (errorResponse) {
$scope.error = errorResponse.data;
}
);
};
I am now using node multiparty for the Node.js controller:
exports.create = function(req, res) {
var form = new multiparty.Form();
form.parse(req, function(err, fields, files) {
//res.writeHead(200, {'content-type': 'text/plain'});
//res.end(util.inspect({fields: fields, files: files}));
var file = files.file[0];
var contentType = file.headers['content-type'];
var tmpPath = file.path;
var extIndex = tmpPath.lastIndexOf('.');
var extension = (extIndex < 0) ? '' : tmpPath.substr(extIndex);
// uuid is for generating unique filenames.
//var fileName = uuid.v4() + extension;
var fileName = tmpPath;
var destPath = 'uploads/' + fileName;
// Server side file type checker.
if (contentType !== 'image/png' && contentType !== 'image/jpeg') {
fs.unlink(tmpPath);
return res.status(400).send({
message: 'Unsupported file type'
});
}
fs.rename(tmpPath, destPath, function(err) {
if (err) {
return res.status(400).send({
message: 'Image is not saved'
});
}
fs.unlink(tmpPath, function() {
if (err) {
return res.status(400).send({
message: 'Impossible to delete temp file'
});
}
});
console.log(destPath);
//return res.jsonp(destPath);
});
var campaign = new Campaign(JSON.parse(fields.campaign[0]));
campaign.user = req.user;
campaign.save(function(err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.jsonp(campaign);
}
});
});
};
I still get an error, but I do not think is related with the file upload. What do you think?
/home/maurizio/Workspace/bdf-v1/node_modules/mongoose/lib/utils.js:413
throw err;
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:691:11)
at ServerResponse.header (/home/maurizio/Workspace/bdf-v1/node_modules/express/lib/response.js:592:10)
at ServerResponse.send (/home/maurizio/Workspace/bdf-v1/node_modules/express/lib/response.js:144:12)
at ServerResponse.jsonp (/home/maurizio/Workspace/bdf-v1/node_modules/express/lib/response.js:301:15)
at Promise. (/home/maurizio/Workspace/bdf-v1/app/controllers/campaigns.server.controller.js:67:9)
at Promise. (/home/maurizio/Workspace/bdf-v1/node_modules/mongoose/node_modules/mpromise/lib/promise.js:177:8)
Using res.status(400).send... or res.jsonp() will send data back to the client starting with the headers. Your script has these statements falling through, but the subsequent ones cannot be executed since data has already been sent to the client.
The returns you have will end the execution of the method they're invoked in, but the script will just continue to the next method where it will encounter another express send(). In your case, fs.rename will send() the 400, but will encounter another send() when it reaches the campaign.save method where it will throw the error.
Take your calls of return res.status(400).send(), and instead set the message as a string variable, and make the res.status(400).send() call in your final conditional statement if an error is present.
Essentially, make sure a send() or jsonp() invocation can only be made once in your script.

Angular Form Post

I have the following code and when I submit the request; I get request failed. The data is not going to the server. Any idea why?
All I need is a simple form submission with the code below. I think the issue is where I'm collecting the form data using the config section. I looked around and that's how I added that. Any help will be appreciated.
Thanks.
<!-- Main Content -->
<div class="container">
<div class="page-header" ng-controller="NotesCtrl">
<h1>{{title}}</h1>
<form class="row-height" name="Form1" ng-submit="processForm('ajaxSubmitResult')">
<!--ng-submit="processForm(formData, 'ajaxSubmitResult') -->
First Name:
<input type="text" ng-model="formData.firstname" class="spacer" required/>
Last Name:
<input type="text" ng-model="formData.lastname" class="spacer" required/>
<!--<button class="btn btn-primary" ng-click="insert(formData)">Add</button>-->
<button type="submit" class="btn btn-success">Add Name</button>
</form>
<hr/>
<h4>Raw Data</h4>
{{formData}}
<hr/>
<h4>Submit Results</h4>
<span id="submitDebugText">{{ajaxSubmitResult | json}}</span>
</div>
</div>
<script>
// define angular module/app
var formApp = angular.module('formApp', []);
function NotesCtrl($scope, $http) {
$scope.title = "Test App";
$scope.formData = {};
$scope.processForm = function (resultVarName) {
var config = {
params: {
'firstname': $scope.firstname,
'lastname': $scope.lastname
}
};
$http.post("//", null, config)
.success(function (data, status, headers, config) {
$scope[resultVarName] = data;
})
.error(function (data, status, headers, config) {
$scope[resultVarName] = "bugger! Errors.";
});
};
}
</script>
When you do something like this in the view:
<input type="text" ng-model="formData.firstname" class="spacer" required/>
In the controller, you access the property with
$scope.formData.firstName
This issue seems to be that you aren't including the formData here:
var config = {
params: {
'firstname': $scope.firstname,
'lastname': $scope.lastname
}
};
Change that to
var config = {
params: {
'firstname': $scope.formData.firstname,
'lastname': $scope.formData.lastname
}
};
And you should be good to go.

Resources