Angular Schema Form Load Data from JSON - javascript

I'm an hardware engineer trying to create an in-house software tool. I thought that I would be able to do so quite easily, but there are a few too many unknowns for me to progress.
I'm trying to create an in-house software solution for managing orders. I have defined a JSON Schema that is valid.
I want to set up a webpage where I can create a new order by filling out a web form. The data should then be stored as a JSON text file. I also want to be able to load a JSON text file, pre-populate the form with the current values, make some changes, and then save the changes.
I've done similar things in php and mysql, but I want to use JSON files to be able to make changes to the software tool without having to fiddle around with a database structure. I also see it as a good learning opportunity.
I'm trying to use auto generated forms (schemaform.io), and I've gotten the following code to work:
<!DOCTYPE html>
<html >
<head>
</head>
<body ng-app="test" ng-controller="FormController">
<form name="ngform"
sf-schema="schema"
sf-form="form"
sf-model="model"></form>
<script type="text/javascript" src="../bower_components/angular/angular.js"></script>
<script type="text/javascript" src="../bower_components/angular-sanitize/angular-sanitize.min.js"></script>
<script type="text/javascript" src="../bower_components/tv4/tv4.js"></script>
<script type="text/javascript" src="../bower_components/objectpath/lib/ObjectPath.js"></script>
<script type="text/javascript" src="../bower_components/angular-schema-form/dist/schema-form.min.js"></script>
<script type="text/javascript" src="../bower_components/angular-schema-form/dist/bootstrap-decorator.min.js"></script>
<script type="text/javascript" src="../bower_components/jquery/dist/jquery.js"></script>
</script>
<script>
/*
$.getJSON("data/order.json", function(orderTemplateJson) {
console.log(orderTemplateJson); // this will show the info it in firebug console
$scope.$broadcast('schemaFormRedraw')
});
*/
var app = angular.module('test',['schemaForm']);
app.controller('FormController', function($scope,$http){
$scope.schema = {
// A long long string of text goes here
};
$scope.form = [
"*",
{
type: "submit",
title: "Save"
}
];
$scope.model = {};
})
</script>
</body>
</html>
I now want to load the JSON schema from a file. I tried to move the code into the callback of a getJSON call, but I got the following error message:
Uncaught Error: [$injector:modulerr] Failed to instantiate module test due to:
Error: [$injector:nomod] Module 'test' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
$.getJSON("data/order.json", function(orderTemplateJson) {
console.log(orderTemplateJson);
//Moved all the angular module code to here
});
I've tried various things, but the problem is likely that I don't really know what I'm doing.. Any help would be greatly appreciated.
Also, does anyone have any pointers on how I can pre-load the form with data from a JSON-file that contains data (and fits the schema)?
Thank you..
/ Martin

While using angular it's good to do things the angular way. So first thing is that you should use angular's $http to load file instead of jQuery's $.getJSON. So in your controller you can do:
app.controller('FormController', function($scope,$http){
$http.get("data/order.json").then(
function success(response) {
// please note that as this is asynchronous,
// the $scope.schema will be available after response
// has been received but this should be ok
$scope.schema = angular.fromJson(response.data);
},
function error(response) { /* handle error */ });
// do other stuff
});
then angular $http API reference will be helpful
there are other things to consider using angular however it's worth to invest some time to familiarize with the angular way and benefit from it relatively quickly.
Even more helpful would be to use $resource instead of $http as it is dedicated to deal with json (and REST actually).

Related

Retrieve part of json file from an external website (sparkfun)

This question might be quite specific to sparkfun, but I still wish to make it as a general question due to my limited experience in javascript.
I have been using the follow html and javascript (d3.js) file to load json data from sparkfun data server:
index.html
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var data_sensor;
var url = "https://data.sparkfun.com/output/w5nEnw974mswgrx0ALOE.json"
d3.json(url, function (error,json) {
if (error) throw error;
data_sensor=json;
console.log(data_sensor)
})
</script>
</body>
After running the script, i will end up with all data array stored in variable data_sensor for post-analyse.
What i wish to do now is to create a dash board that downloads and stores only the latest value. i understand that i could just use the first value in the data_sensor to do so (i.e., data_sensor[0]) but such method becomes quite inefficient with the growth of data.
Thanks!
When I've wanted to load JSON from somewhere I've always used jQuery:
Import jQuery like this:
<script src="jquery-3.2.1.min.js"></script>
Then you can do something like this to get your JSON file:
var data_sensor;
var url = "https://data.sparkfun.com/output/w5nEnw974mswgrx0ALOE.json"
$.getJSON(url, function(data) {
data_sensor = data;
console.log(data_sensor)
});
Hope that helps!
Not an expert here, but their docs state tat you can use paging to get the first 250kb of data:
var url = "https://data.sparkfun.com/output/w5nEnw974mswgrx0ALOE.json?page=1";
You can get your first object/set of data, and I'm afraid there's no general way to take only part of any API response - request is request, it could send you every possible data depending on architecture, from "OK" string to 200MB of data. Carefully reading docs is your best bet.

Output data from TaffyDB

I'm new to JavaScript and am trying to build a script that performs some data management activities(Basically query based data fetching from a database and then displaying it on a webpage).
I generally would do this on the server side with PHP and mysql but my boss want's to see a "sample" before investing in servers etc. (He has no technical knowledge regarding PHP,MySQL etc)
Now without a server I was looking for a way to build a similar system on the client side mostly via javascript. Just to demonstrate the logic I plan on implementing.
For the database part I decided to use TaffyDB, however am having issues getting an output from the database(Display the data on a webpage)
Here's my code
<!DOCTYPE html>
<html>
<head>
<script src="taffydb-master\taffy.js"></script>
<script>
var companies = TAFFY
([
{name:"New York",state:"WA"},
{name:"New Shire",state:"WE"},
{name:"Las Vegas",state:"NV"},
{name:"Boston",state:"MA"}
]);
var cities = new Array();
var cities = companies().select("name");
</script>
</head>
<body>
<script>
document.write = (cities[1]);
</script>
</body>
</html>
I know there's some silly mistake in there but really can't find it. I tried using the developer's tools (Mozilla's default one) but it returns no issues. I basically just get a blank white page when I load this file.
You are using document.write incorrectly. It is a method.
If you change your code to:
<script>
document.write(cities[1]);
</script>
then you will get this output:
New Shire
Also, you should probably wrap the output in some element like so:
<script>
document.write("<p>" + cities[1] + "</p>");
</script>

Reading and writing to a server-side file in AngularJS

I'm attempting to create a simple guestbook with AngularJS, and read and write the names to a simple file. Trouble is, I can't seem to get my code to even read from the file.
This is my directory structure:
This is index.html:
<!DOCTYPE html>
<html ng-app>
<head>
<meta charset="ISO-8859-1">
<title>GuestBook</title>
<script src="http://code.angularjs.org/angular-1.0.0rc3.min.js"></script>
<script type="text/javascript" src="javascript/user.js"></script>
</head>
<body>
<h1>Welcome!</h1>
<div ng-controller="UserCtrl">
<ul class="unstyled">
<li ng-repeat="user in users">
{{user}}
</li>
</ul>
</div>
</body>
</html>
This is user.js (Based off this question/answer):
function UserCtrl($scope) {
$scope.users = $(function() {
$.get('data/users', function(data) {
var array = data.split(',');
console.log(array);
});
});
}
And this is my users file:
John,Jacob,James
I'm expecting this outcome:
Welcome!
John
Jacob
James
But instead, all I get is:
Welcome!
So my question is, how can I populate $scope.users with the names in the users file?
I know I've got my AngularJS set up correctly because I was able to get the desired result when I hard-coded it:
$scope.users =[John,Jacob,James];
I've also spent a lot of time googling and searching Stack Overflow for how to read and write to a file with JavaScript and/or AngularJS, but:
No one seems to be trying to do exactly what I'm trying to do;The instructions are either confusing or not really applicable to what I'm trying to do.
I'm also not sure where to begin to write code that will persist names to the users file -- but I'll be happy if I can just read the file for now, and ask how to write to it later in a separate question. (But extra gratitude if you do also show me how to write to it.)
Try injecting angular's $http service into your controller first of all. And make sure you add a '/' before your 'data/users' path. (/data/users)
function UserCtrl($scope, $http) {
$scope.users = [];
$http.get('/data/users')
.success(function(data, status, headers, config) {
if (data && status === 200) {
$scope.users = data.split(',');
console.log($scope.users);
}
});
});
}
You can check your console to see what kind of data is being returned. (Network tab)
edit: just realized the $(function ... part didn't make sense.
The problem with your code is in this stub -
$scope.users = $(function() {
$.get('data/users', function(data) {
var array = data.split(',');
console.log(array);
});
});
Here $scope.users is not the array variable. Instead, it is whatever $() returns.
Your anonymous function is passed only as a parameter to $ function.
Rewrite your controller this way -
function UserCtrl($scope, $http) {
$scope.users = [] // Initialize with an empty array
$http.get('data/users').success(function(data, status, headers, config) {
// When the request is successful, add value to $scope.users
$scope.users = data.split(',')
})
}
And now, since you have
<li ng-repeat="user in users">
{{user}}
</li>
in your view, angular will set up a watch on $scope.users variable.
If the value of $scope.users changes anytime in the future, angular will automatically
update the view.
EDIT -
Along with the above edit, you need to make sure all the files are being served via a web server on the same host:port. Browsers limit AJAX access to another domain:port. Here is a quick way to do start a http server -
Go to the project directory using terminal and type in
python -m SimpleHTTPServer for python
or
ruby -run -e httpd -- -p 8000 . for ruby.
Both will start a basic HTTP server at port 8000, serving content from that particular directory. Having done this, your index.html will be at http://localhost:8000/index.html and your data file should be accessibe as http://localhost:8000/data/user.js (your javascript can still use /data/user.js).
It turns out I can't do what I'm trying to do the way I'm trying to do it. JavaScript by itself can't read files on the Server-Side, only on the Client-Side. To read and persist data, JavaScript has to make calls to a "Back-end" or server, written in something like Java, which isn't just a Browser scripting language.
you entered 'users' instead of 'users.txt' as filename.
This works just fine to me:
function UserCtrl($scope, $http) {
$scope.users = []
$http.get('data/users.txt').success(function(data, status, headers, config) {
$scope.users = data.split(',')
})}

Javascript to read file names under a directory

I have placed some XML files under a directory. I need to populate a drop down using javascript to display all those XML file names. How do I do that?
You've been way too broad when it comes to circumstances and situation, so I'll be broad back with an answer.
Given the following:
The web-page with the <select> you need to populate is hosted on the same server as the file list.
The server has the ability to use a server-side language (e.g. PHP, ASP)
You don't mind, or can at least decipher jQuery code (makes what I'm about to post more about the concept than the practice)
You will need something like the following setup:
Create a server-side file that dumps a list of file names
You're going to need to look up some way to retrieve and dump the list of the files. This is so JavaScript & AJAX can go fetch this list and dump in in to the drop-down list. Example output of said script (which I'm aliasing as /server-side-file-list in the JavaScript below)
file-001.xml
file-002.xml
file-003.xml
file-004.xml
Setup the <select> on your page
<!-- Somewhere in the page -->
<select id="xml-file-list" name="xml-file-list"></select>
Setup the JavaScript/Ajax code
<!-- This should go in the <head></head> portion of your page with the select -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$.ajax({
url: '/server-side-file-list',
success: function(d){
$.each(d.split(/[\r\n]+/),function(i,e){
$('<option />',{ value: e }).text(e).appendTo('#xml-file-list');
});
}
});
</script>
Basic work-flow:
HTML page loads up with an empty <select>
jQuery takes over and fetches a list of files from that /server-side-file-list script using AJAX (behind the scenes)
The results are returned and placed in to the <select> as <option>s.
Done.
--
Food for thought:
A better method may be to load your file list in to the page at run time (if possible). That is to say, if the page you're working on is an ASP or PHP or other type of server-side language page, you can retrieve the file list when the page is called upon and load it at that time (and avoid using javascript altogether).
Assuming you're talking about local files, you need a browser that supports the W3C FileSystem API.
You can test for compatibility at www.html5test.com
If you're completely agnostic about the name of xml file you will need a server-side language to get a list of file of a server directory.
Otherwise, if you're in control of filenames, a workaround could be give them a progressive name (e.g. 1.xml, 2.xml...) and try to make some chained ajax HEAD calls.
If the ajax request of 1.xml returns a 200 server status, then ask for 2.xml and so on, until you get a 404 error. For each ajax call you can add the name to an array and then use it to create a dynamic select.
Of course, for a matter of performance, this should be intended only as a workaround and it's not reliable at all, since a 404 could occur even if the resource exists, so I strongly suggest to use a server side language
anyway this is a jQuery 1.5+ example explaining the workaround. Suppose you have 1.xml, 2.xml and 3.xml. The HTML is just an empty select
<select id="xmlfiles"></select>
Javascript/jQuery
<script>
$(document).ready(function() {
/**
* we need to only know if the resource exists or not
*/
$.ajaxSetup({ type : "head" });
/**
* Function reading xml file. When deferred has been resolved
* (when first 404 occurs) an array of filename is passed.
*/
function getXMLFile(path) {
var deferred = $.Deferred(),
xmlFiles = [];
(function getFile( i ) {
var url = [path, i, '.xml'].join('');
$.when($.ajax(url))
.done(function() {
xmlFiles.push(url);
getFile( ++i );
})
.fail(function() {
deferred.resolve(xmlFiles);
});
}(1));
return deferred.promise();
};
/**
* when we have read xmlfiles in "./" then for each file
* retrieved append an option
*/
$.when(getXMLFile('./')).then(function(file) {
var select = $('#xmlfiles');
/* create options */
$.each(file, function(i, filename) {
var option = $('<option></option>');
option.html(filename).attr('value', filename).appendTo(select)
})
});
});
</script>
and this shows a select with options
./1.xml
./2.xml
./3.xml
(Sorry for my verbosity)

Using last.fm API in javascript

I have very little experience with web development. I have a little experience with HTML and I am learning JavaScript right now. I created a program in Java using a a last.fm library for Java. I was able to get user information, artist information, and venue information. Now I want to try and do that in a webpage, which is where my problem occurs.
I'm using the javascript last.fm api given here http://github.com/fxb/javascript-last.fm-api
I've downloaded all the .js files and they are in the same directory as my .htm file.
This is my code so far.
<html>
<body>
<script type="text/javascript" src="lastfm.api.md5.js"></script>
<script type="text/javascript" src="lastfm.api.js"></script>
<script type="text/javascript" src="lastfm.api.cache.js"></script>
<script type="text/javascript">
var cache = new LastFMCache();
var lastfm = new LastFM({
apiKey : 'c9946d11aaaaaaaaaaaaaaaaaaaaaaaace',
apiSecret : '9dabf9aaaaaaaaaaaaaaaaxxx11ec3c7a993',
cache : cache
});
lastfm.artist.getInfo({artist: 'The xx'}, {success: function(data){
/* Use Data */
}, error: function(code, message){
/* Show error message. */
}});
</script>
</body>
</html>
I've dug around in the included .js files to try and understand what is going on. So on my initialization of lastfm, I am passing in some objects with associated values, which are then applied to lastfm. If I try and access them through document.write(lastfm.apiKey) I get an undefined value, which I don't really understand.
Also I see that I am calling getInfo and passing in 'The xx' and everything that follows. I don't understand how to use that Data that I believe is returned as a JSON response. How can I print the bio that is associated with that artist?
the code that should go where you have written /* Use Data */ will refer to items such as data.bio. Try alert(data) to see what's in there.
I would also highly recommend using a JavaScript debugging console such as FireBug in order to really see what's going on.
i just used this, and yeah. you just need to console.log(data) in the success to get info about the data that is being passed back from last fm

Categories