Folks I have a form on my website who's data I want to store in a json file.
Here is the code for the form:
<form>
<input ng-model="obj.firstname">
<input ng-model="obj.lastname">
<button ng-click="storedata()">Click here to store data</button>
</form>
My Angular code is as below:
var myApp = angular.module('app', ['ui.bootstrap.dialog','ngResource']);
myApp.controller('TestCtrl', function($scope,$dialog,TestResource) {
$scope.obj = {};
$scope.obj.firstname = "Mahatma";
$scope.obj.lastname = "Gandhi";
$scope.storedata = function() {
console.log("Storing Data now");
TestResource.save($scope.obj);
console.log("Data should have been stored");
}
});
myApp.factory('TestResource', ['$resource', function($resource) {
return $resource('test.json', {}, {} );
}]);
The problem is that the data does not get stored. Am I missing something here ?
Here is a plunkr : http://plnkr.co/edit/gist:3662702
ngResource is an Angular service designed to interact with RESTful server side data sources (see ngResource docs). The angular js tutorials tend to reference local JSON files since they're meant to be stand-alone examples which anyone can download and run locally without the need for a back-end server. But you'll notice the tutorials only read data from the JSON files, they cannot update them.
If you're looking to save data client side, check out LocalStorage (http://diveintohtml5.info/storage.html).
If you're trying to save the data server side, you'll need to setup some back end service (via NodeJS, PHP, .NET, Ruby, Python, and many other frameworks..)
Related
I need to upload image and video files to the server in an Angular application using Laravel 5.1 as the back end. All Ajax requests need to go to the Laravel controller first, and we have the code there for how the file gets handled when it gets there. We have previously done normal HTML forms to submit file uploads to the controller, but in this case we need to avoid the page refresh of a form, so I am attempting this in Ajax through Angular.
What information do I need to send to the Laravel controller with Ajax that was being sent to the controller via an HTML form previously?
This is the code in the Laravel controller that handled the file information once it got there. That's what I need to figure out how to send, so I can hopefully reuse this code:
$promotion = Promotion::find($id);
if (Input::hasFile('img_path')){
$path = public_path().'/images/promotion/'.$id.'/';
$file_path = $path.'promotion.png';
$delete = File::delete($file_path);
$file = Input::file('img_path');
$uploadSuccess = $file->move($path, 'promotion.png');
$promotion->img_path = '/images/promotion/'.$id.'/promotion.png';
}
if (Input::hasFile('video_path')){
$path = public_path().'/video/promotion/'.$id.'/';
$file_path = $path.'promotion.mp4';
$delete = File::delete($file_path);
$file = Input::file('video_path');
$uploadSuccess = $file->move($path, 'promotion.mp4');
$promotion->video_path = '/video/promotion/'.$id.'/promotion.mp4';
}
As you can see above, we are converting whatever file we get to a PNG with the file name promotion.png so it's easy to fetch, and we are only accepting .mp4 video format. Because of that, we don't need to worry about checking if the file exists and is it ok to overwrite it. That's why you can see in the code we delete any existing file of that name before saving.
The HTML was just an input with a type of "file:
<input type="file" id="img_path" name="img_path" class="promo-img-path" accept="image/*">
We are using Angular now so I can't just send the above through an HTML form anymore. That's what I need to figure out how to do.
We are two developers just doing our best, so I'm sure there is a better way of doing this. However before I refactor this whole thing, I'm hoping I can use Angular (or jQuery as a last resort) to just send the controller whatever file data Laravel needs in order to make the above code work. The answer may be as simple as "send a PUT to the method in that controller above, but instead of a normal JSON payload, use file info in this format and you can gather that info with..."
I would also appreciate any tips on better ways I can do this in the future.
How to POST FormData Using the $http Service
When using the FormData API to POST files and data, it is important to set the Content-Type header to undefined.
var fd = new FormData()
for (var i in $scope.files) {
fd.append("fileToUpload", $scope.files[i]);
}
var config = {headers: {'Content-Type': undefined}};
var httpPromise = $http.post(url, fd, config);
By default the AngularJS framework uses content type application/json. By setting Content-Type: undefined, the AngularJS framework omits the content type header allowing the XHR API to set the content type. When sending a FormData object, the XHR API sets the content type to multipart/form-data with the proper boundaries and base64 encoding.
For more information, see MDN Web API Reference - XHR Send method
How did you get the file information into $scope.files?
How to enable <input type="file"> to work with ng-model
This directive also enables <input type="file"> to automatically work with the ng-change and ng-form directives.
angular.module("app",[]);
angular.module("app").directive("selectFilesNg", function() {
return {
require: "ngModel",
link: function postLink(scope,elem,attrs,ngModel) {
elem.on("change", function(e) {
var files = elem[0].files;
ngModel.$setViewValue(files);
})
}
}
});
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
<h1>AngularJS Input `type=file` Demo</h1>
<input type="file" select-files-ng ng-model="fileArray" multiple>
<code><table ng-show="fileArray.length">
<tr><td>Name</td><td>Date</td><td>Size</td><td>Type</td><tr>
<tr ng-repeat="file in fileArray">
<td>{{file.name}}</td>
<td>{{file.lastModified | date : 'MMMdd,yyyy'}}</td>
<td>{{file.size}}</td>
<td>{{file.type}}</td>
</tr>
</table></code>
</body>
RECOMMENDED: POST Binary Files Directly
Posting binary files with multi-part/form-data is inefficient as the base64 encoding adds an extra 33% overhead. If the server API accepts POSTs with binary data, post the file directly.
See How to POST binary files with AngularJS (with DEMO)
I am making a local static webpage that has no backend. I've only got data in a json file. I will be zipping up the code and sending it to someone.
I cannot import the file into index.html because the code that needs it (a factory) is separate in a factory.js file.
e.g.
<script src="LOCAL.js"></script>
Won't work because i don't do any logic on the index.html page.
I cannot do $http because I get a cross domain error and it's not acceptable.
How can I get my json file locally into my factory? I have NodeJS and NPM. However, the person I'm sending the webpage to will also need to run it without any problems.
You could mock out a service that just fetches a JSON file and loads it in, or you could mock the JSON out directly in the script.
If you wanted to do a service, you could try something like
module.exports = {
getJSON: function() {
return $http.get('./path/to/file.json')
.then(function(json){
//do something with your json
return json;
})
},
getJSONObject: function() {
return {
// add your json in here //
}
}
}
I have a simple angular resource that I've defined as below:
CompanyService.factory('CompanyService',
function ($resource) {
return $resource('https://baseurl.com/api/values/');
}
);
I then have a controller that calls that resource passing in a success and fail function:
.controller('companyList', function($scope, CompanyService) {
$scope.companies = CompanyService.query(
function(data) {
console.log(data);
return data;
},
function(error){
console.log("Error:");
console.log(error);
}
);
The rest API is a .NET MVC Web API that is extremely basic. I've configured it to return JSON and it simply returns an array of two objects like below. I've also enabled CORS so my angular app, which is hosted in a different domain, can call the api.
[{ID:1, Name:"TEST1"}, {ID:2, Name:"TEST2"}]
I've tested the REST call using jquery and just straight call through browser. All was functional (including the cross site scripting when calling from my angular app just using a straight JavaScript HTTP call).
When I try to call the api from my controller however, it always ends up in the error function. The error object contains a data property that is always populated with the string "resource is required|resource is required|undefined"
When I check the network I see no call to the values end point. It's as if the call is failing before ever being made.
If I change out the url to point to some sample REST api like https://jsonplaceholder.typicode.com/users/ it works fine and I'm able to see the call to "users" in the network traffic, which makes me think there is something wrong with my C# REST endpoint, however all my tests to call the REST endpoint outside of angular work successfully.
Can anyone help? I can't find anyone reporting this issues before anywhere on the net.
should the code be the one below? i didn't test it, just guess.
myModule.factory('CompanyService',
function ($resource) {
return $resource('https://baseurl.com/api/values/');
}
)
.controller('companyList', function($scope, CompanyService) {
CompanyService.query(
function(data) {
$scope.companies = data;
console.log(data);
return data;
},
function(error){
console.log("Error:");
console.log(error);
}
);
I ended up rebuilding my angular app from scratch. My first app was from the angular-seed github and had a handful of libraries already added in for testing and other things. One of those things is was was leading to this error as once I started a new project completely from scratch and added in angular and my REST call things worked perfectly. I've already spent too much time working through this so not going to spend any more time identifying exactly what it is but in case anyone else runs into the problem I did want to answer this one and close the book on it.
I'm new to AngularJs. How to save data from Api into couchdb using AngularJs and retrieve it back. Can anyone give example coding.
'Cause CouchDB has a REST interface you can use these AngularJS services to access its functionalities:
$resource
$http
Eventually here is a tutorial with a step-by-step example:
http://thewebhacker.com/rapid-app-prototyping-with-angularjs-and-couchdb/
Refer this dummy code, this will basically calls URL defined by Couch and returns JSON data,
function getItems () {
$http.get(appSettings.db + '/_design/expenses/_view/byName')
.success(function (data) {
$scope.items = data.rows;
});
}
getItems();
For more info, plz refer this link:
http://www.sitepoint.com/tracking-expenses-couchdb-angular/
I'm making a mobile app using ionic (based on the AngularJS framework) where I want to display data from a RESTfull API. I'm pretty new to AngularJS so I'm not familiar with the best practices. I want to get data from this API but with a weeknumber parameters in the URL so I can get data from specific weeks. I have looked especially to the example of the AngularJS website.
This is what I have in my services:
var eventServices = angular.module('starter.services', ['ngResource']);
eventServices.factory('EventServiceAPI',['$resource',
function($resource) {
return $resource('http://localhost:8080/schedulingAPI/plannedevents?weeknumber=:weeknumber', {}, {
query: { method: 'GET', params:{weeknumber:'weeknumber'}, isArray: true}
});
}]);
This is what I have in my controller to get the API data:
$scope.events = EventServiceAPI.get({weeknumber: 7});
However, I still keep getting the error:
Error: [$resource:badcfg] object
When I use the full API URL in services and $scope.events = EventServiceAPI.query() in my controller, the full API-data is displayed without error.
I also don't get where to put the parameters; in the brackets after the resource URL or the params option in the query method.
Edit:
The output of http://localhost:8080/schedulingAPI/plannedevents?weeknumber=:weeknumber
[{"id":2985,"event":{"eventId":589,"subject":"Masterproef","year":2014,"weekNumber":7,"dayNumber":6,"startHour":8,"startMinute":10,"endHour":12,"endMinute":45,"startTime":"2014-02-14T07:10:00Z","endTime":"2014-02-14T11:45:00Z","classgroups":[{"id":8,"name":"4ELICTI"},{"id":4,"name":"4ENAU"},{"id":10,"name":"4ELICTE"},{"id":1,"name":"4CHB"},{"id":3,"name":"4ENEL"},{"id":9,"name":"4EMEM"},{"id":2,"name":"4CHC"},[]],"teacher":null},"rooms":[{"id":24,"abbr":"D015"}]},{"id":4021,"event":{"eventId":604,"subject":"Bedrijfsbeleid 2 hc","year":2014,"weekNumber":7,"dayNumber":6,"startHour":8,"startMinute":10,"endHour":9,"endMinute":35,"startTime":"2014-02-14T07:10:00Z","endTime":"2014-02-14T08:35:00Z","classgroups":[{"id":6,"name":"4ELICT"},[]],"teacher":null},"rooms":[{"id":44,"abbr":"G120"}]}]
Replace params:{weeknumber:'weeknumber'} with params:{weeknumber:'#weeknumber'}, notice the #.
If the parameter value is prefixed with # then the value of that
parameter is extracted from the data object (useful for non-GET
operations).
From angular documentation
And call your function with query:
$scope.events = EventServiceAPI.query({weeknumber: 7});
Actually, you can simplify your resource declaration like this:
eventServices.factory('EventServiceAPI',['$resource',
function($resource) {
return $resource('http://localhost:8080/schedulingAPI/plannedevents');
});
}]);
Angular will automatically append the query string for you