How to plot line graph using json in Highchart? - json

This is a code for genearting graph in jsp.But the code is to be fail.Actually i using highchart for developing graph,but showeing an error..
<%# page contentType="text/html; charset=iso-8859-1" language="java" import="java.sql.*" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<script>
$(document).ready(function() {
var line2=$.parseJSON(document.getElementById("test").value);
var mydata = [[]];
var mydata1 = [[]];
for(var i=0; i<line2.length; i++)
{
//mydata[0].push([line2[i].time,line2[i].valueint]);
mydata[0].push([line2[i].time]);
mydata1[0].push([line2[i].valueint]);
}
alert(mydata);
alert(mydata1);
$('#container').highcharts({
title: {
text: 'Monthly Average Temperature',
x: -20 //center
},
subtitle: {
text: 'Source: WorldClimate.com',
x: -20
},
xAxis: {
categories: mydata
},
yAxis: {
title: {
text: 'Temperature (°C)'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
valueSuffix: '°C'
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
borderWidth: 0
},
series: [{
name: 'Temp',
data: mydata1
}]
});
});
</script>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
</head>
<body>
<input type="hidden" id ="test" value='[{"time":"2013-07-02 18:33:52","valueint":25.000},{"time":"2013-07-02 18:34:22","valueint":27.000},{"time":"2013-07-02 18:34:52","valueint":25.000}]'>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
</body>
</html>
Actually this is my code ..but not to generete graph baesd on time vs temperature ..Alerts are genereted but not in graph please update this code.

Two things:
categories should be an array of strings, so:
remove extra array here: var mydata = [[]]; -> var mydata = [];
remove extra array here: mydata[0].push([line2[i].time]); -> mydata.push(line2[i].time);
data should be an array of numbers, so remove extra arrays the same way as for categories.

Related

How do I send the PDF generated using pdf-creator-node to WhatsApp?

I am trying to find a solution that generates PDF using HTML template and be able to send it on WhatsApp. I am using pdf-creator-node but I am not able to send this PDF to WhatsApp.
I tried using get-stream but it gives source.on('error', function() {}); error.
index.js
var pdf = require("pdf-creator-node");
var fs = require("fs");
let wa = require("./sendTemplate")
require("dotenv").config()
const getStream = require('get-stream')
// Read HTML Template
async function createCertificate() {
var html = fs.readFileSync("template.html", "utf8")
var options = {
format: "A3",
orientation: "portrait",
border: "10mm",
header: {
height: "45mm",
contents: '<div style="text-align: center;">Author: Shyam Hajare</div>'
},
footer: {
height: "28mm",
contents: {
first: 'Cover page',
2: 'Second page', // Any page number is working. 1-based index
default: '<span style="color: #444;">{{page}}</span>/<span>{{pages}}</span>', // fallback value
last: 'Last Page'
}
}
};
var users = [
{
name: "Shyam",
age: "26",
},
{
name: "Navjot",
age: "26",
},
{
name: "Vitthal",
age: "26",
},
];
var document = {
html: html,
data: {
users: users,
},
path: "./output.pdf",
type: "",
};
pdf
.create(document, options)
.then(async (res) => {
console.log(res);
resolve(await getStream.buffer(document))
})
.catch((error) => {
console.error(error);
});
}
const pdfBuffer = createCertificate()
wa.sendMedia(pdfBuffer, "name_output.pdf", "number")
template.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello world!</title>
</head>
<body>
<h1>User List</h1>
<ul>
{{#each users}}
<li>Name: {{this.name}}</li>
<li>Age: {{this.age}}</li>
<br />
{{/each}}
</ul>
</body>
</html>
I am using WATI as my WhatsApp API provider
YouTube reference: https://www.youtube.com/watch?v=SCQzIRNT-eU&ab_channel=CodingShiksha

How to efficiently use a template as a variable in Flask?

I am using flask to develop my website and i often have to use graph to display data, so I'd like to have a route that display a graph and then use it as a template. The way I found to do it is the following:
Two html files : tender.html and template.html with the first one used as the file to display to the user and the second one used as a template for graph that can be re-used in other routes
template.html :
<!DOCTYPE html>
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.0.0/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#2.0.0"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js" integrity="sha512-UXumZrZNiOwnTcZSHLOfcTs0aos2MzBWHXOHOuB0J/R44QB0dwY5JgfbvljXcklVf65Gc4El6RjZ+lnwd2az2g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/1.2.1/chartjs-plugin-zoom.min.js" integrity="sha512-klQv6lz2YR+MecyFYMFRuU2eAl8IPRo6zHnsc9n142TJuJHS8CG0ix4Oq9na9ceeg1u5EkBfZsFcV3U7J51iew==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div class="chart-container" style=""><canvas id="myChart-1"></canvas></div>
<div>div-test</div>
<script>
const dataset_1 = [{
label: "Spread of ",
type: 'line',
backgroundColor: "blue",
order : 3,
pointRadius:0,
borderWidth: 1,
borderWidth: 1,
borderColor:"blue",
data: {{ data | safe }},
yAxisID: 'y'
},
];
const data_1 = {
labels: {{ label | safe }},
datasets : dataset_1
};
const zoomOptions = {
animations: false,
tranistions: false,
pan: {
enabled: true,
mode: 'x',
},
zoom: {
wheel: {
enabled: true,
},
drag: {
enabled: true,
modifierKey: 'ctrl',
},
mode: 'x',
onZoomComplete({chart}) {
// This update is needed to display up to date zoom level in the title.
// Without this, previous zoom level is displayed.
// The reason is: title uses the same beforeUpdate hook, and is evaluated before zoom.
chart.update('none');
}
}
};
const config_1 = {
data: data_1,
options: {
animations:false,
transitions:false,
responsive: true,
interaction: {
},
stacked: false,
plugins: {
zoom : zoomOptions,
title: {
display: true,
text: "bla bla"
}
},
scales: {
y: {
type: 'linear',
display: true,
position: 'left',
borderWidth : 0.001,
},
x: {
display: true,
grid :{
display:false
},
},
},
},
};
const myChart_1 = new Chart(document.getElementById('myChart-1'),config_1);
</script>
tender.html :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{% autoescape false %}
{{template}}
{% endautoescape %}
</body>
</html>
The route in my flask app that "join" the two files
#app.route('/test')
def test():
template = render_template('template.html',data=[2,4,1,9,5,2],label=[0,1,2,3,4,5])
return render_template('tender.html', template=template)
Obviously this solution is completely fine but i thought that render_template was meant to only be used with return, at the end of routes so i was wondering wether there was a more natural or prettier way to do the job. I was thinking there was as i have to use autoescape on my template variable to have my stuff rendered.
Thanks for your help already and I can clarify my point if it isn't clear enough !

Send data to another javascript library with vue

With vue, I create a json file with classic asp from Sql Server and import the data. My goal is to place the data I have received on the page and in apexCharts.
The html page I used, getData.js and json from dataSql.asp is as follows.
index.html
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="vue.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js"></script>
<style> textarea { position: fixed; right: 0; top: 0; width: 300px; height: 400px; } </style>
</head>
<body>
<div id="app">
<form id="urlParameterForm">
<input type="date" name="startDate" id="startDate" />
<input type="date" name="endDate" id="endDate" />
<input
type="number"
name="pageNumber"
id="pageNumber"
value="1"
v-on:input="changePage"
/>
<input
type="button"
value="Filter"
id="Filter"
v-on:click="changeFilter"
/>
<p>Page : {{ pageActive }}</p>
</form>
<h3>{{title}}</h3>
<div v-for="dta in dataTable.sqlData">
Height: {{dta.height}}, Type: {{dta.type}}
<ul v-for="dta in dataTable.sqlData.graphData">
<li>{{dta.categorie}} - {{dta.serie}}</li>
</ul>
</div>
<textarea>
{{dataTable}}
</textarea>
</div>
<script src="getData.js"></script>
</body>
</html>
getData.js
const app = new Vue({
el: "#app",
devtools: true,
data: {
dataTable: [],
pageNumber: 1,
pageActive :0,
title:'Graph-1'
},
computed: {
url() {
return './dataSql.asp?pg=' + this.pageNumber
}
},
methods: {
changePage: function (event) {
console.log('Change Page',this.pageNumber);
this.pageNumber = event.target.value;
this.init();
},
changeFilter: function (event) {
console.log('Change Filter');
this.init();
},
init() {
let that = this;
console.log('init call');
$.ajax({
type: "POST",
url: that.url,
data:{
startDate:$('#startDate').val(),
endDate:$('#endDate').val(),
pageNumber:$('#pageNumber').val()
},
success: function (data) {
console.log('data remote call');
console.log(data.sqlData);
that.dataTable = data.sqlData;
}
});
}
},
mounted() {
this.init()
}
})
dataSql.asp response json
[
{
"height": 350,
"type": "bar",
"graphData": [
{
"categorie": "Bursa",
"serie": 4
},
{
"categorie": "Tekirdağ",
"serie": 3
}
]
}
]
When I run the page, the screen calls the data like this and I see the data coming as json.
Under the graph-1 text, the does not show anything as if I have never written this. But I can print json text in the text field as it appears in the upper right corner.
<div v-for="dta in dataTable.sqlData">
Height: {{dta.height}}, Type: {{dta.type}}
<ul v-for="dta in dataTable.sqlData.graphData">
<li>{{dta.categorie}} - {{dta.serie}}</li>
</ul>
</div>
<textarea>
{{dataTable}}
</textarea>
I actually want to assign this data, which I could not show on the page, to x and y variables here.
I need something like the following.
categories: app.dataTable.graphData.categorie;
series: app.dataTable.graphData.serie;
var barBasicChart = {
chart: {
height: 350,
type: 'bar',
},
plotOptions: {
bar: {
horizontal: true,
}
},
dataLabels: {
enabled: false
},
series: [{
data: [4,3] /* vue - json - graphData.serie */
}],
xaxis: {
categories: ['Bursa','Tekirdağ'], /* vue - json - graphData.categories */
},
fill: {
colors: $themeColor
}
}
// Initializing Bar Basic Chart
var bar_basic_chart = new ApexCharts(
document.querySelector("#denemeGrafik"),
barBasicChart
);
bar_basic_chart.render();
Vue seems to have not been developed for a long time. I'm new to vuede too. My goal is to automatically generate html content from json. To change the variables of the scripts I have used (such as apexcharts, xGrid etc.).
Can you suggest if there is another javascript library that I can do these things with?
Except for React and Angular because these two are hard to understand and write.
Your AJAX callback assigns dataTable to data.sqlData:
$.ajax({
//...
success: function (data) {
that.dataTable = data.sqlData;
}
})
Then, your component tries to render dataTable.sqlData, but sqlData was already extracted in the AJAX callback (dataTable is an Array):
<div v-for="dta in dataTable.sqlData">
^^^^^^^ ❌
Solution: You can either update the AJAX callback to return the full response (including sqlData):
$.ajax({
//...
success: function (data) {
that.dataTable = data;
}
})
...or update the template to not dereference sqlData, using dataTable directly:
<div v-for="dta in dataTable">

Highcharts: Highmaps - Choropleth maps - All states are the same color

I have copied the demo code for the United States color axis map from the Highcharts website and substituted my own JSon file of values. The values are showing up in the tooltip and the legend has color gradients and values, but the states are all one medium blue color. The file values range from a few hundred to almost $4 million dollars for the states. This html page is being called in MVC5.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="https://code.highcharts.com/maps/highmaps.js"></script>
<script src="https://code.highcharts.com/maps/modules/data.js"></script>
<script src="https://code.highcharts.com/mapdata/countries/us/us-all.js"></script>
<script>
$(function () {
$.getJSON('/HighChart/GetStates', function (data) {
// Make codes uppercase to match the map data
$.each(data, function () {
this.State = this.State.toUpperCase();
});
// Instanciate the map
$('#container').highcharts('Map', {
chart : {
borderWidth : 1
},
title : {
text : 'Sales per State'
},
legend: {
layout: 'horizontal',
borderWidth: 0,
backgroundColor: 'rgba(255,255,255,0.85)',
floating: true,
verticalAlign: 'top',
y: 25
},
mapNavigation: {
enabled: true
},
colorAxis: {
min: 1,
max: 5000000,
type: 'logarithmic',
minColor: '#EEEEFF',
maxColor: '#000022',
stops: [
[0, '#EFEFFF'],
[.67, '#4444FF'],
[1, '#000022']
]
},
series : [{
animation: {
duration: 1000
},
data : data,
mapData: Highcharts.maps['countries/us/us-all'],
joinBy: ['postal-code', 'State'],
dataLabels: {
enabled: true,
color: '#FFFFFF',
format: '{point.State}'
},
name: 'Total Sales',
tooltip: {
pointFormat: '{point.State}: {point.TotalSales}'
}
}]
});
});
});
</script>
<title>Map</title>
</head>
<body>
<div id="container" style="height: 500px; min-width: 310px; max-width: 600px; margin: 0 auto"></div>
<p>
Return
</p>
</body>
</html>
My Json file is as follows:
[
{"Year":2015,"State":"","TotalQuantity":1318,"TotalSales":0.0000,"IsDistributor":0},
{"Year":2015,"State":"AK","TotalQuantity":19,"TotalSales":4745.6900,"IsDistributor":0},
{"Year":2015,"State":"AL","TotalQuantity":148,"TotalSales":38313.9300,"IsDistributor":0},
{"Year":2015,"State":"AR","TotalQuantity":11,"TotalSales":1610.9500,"IsDistributor":0},
{"Year":2015,"State":"AZ","TotalQuantity":154,"TotalSales":42988.8000,"IsDistributor":0},
{"Year":2015,"State":"CA","TotalQuantity":3640,"TotalSales":1634505.3344,"IsDistributor":0},
{"Year":2015,"State":"CO","TotalQuantity":6200,"TotalSales":3863600.7213,"IsDistributor":0},
{"Year":2015,"State":"CT","TotalQuantity":2240,"TotalSales":400435.9686,"IsDistributor":0},
{"Year":2015,"State":"DE","TotalQuantity":4328,"TotalSales":1236465.4315,"IsDistributor":0},
{"Year":2015,"State":"FL","TotalQuantity":3689,"TotalSales":674759.7803,"IsDistributor":0},
{"Year":2015,"State":"GA","TotalQuantity":3182,"TotalSales":795062.7901,"IsDistributor":0},
{"Year":2015,"State":"HI","TotalQuantity":17,"TotalSales":21887.0000,"IsDistributor":0},
{"Year":2015,"State":"IA","TotalQuantity":227,"TotalSales":58511.3800,"IsDistributor":0},
{"Year":2015,"State":"ID","TotalQuantity":199,"TotalSales":64104.1200,"IsDistributor":0},
{"Year":2015,"State":"IL","TotalQuantity":1356,"TotalSales":481361.1978,"IsDistributor":0},
{"Year":2015,"State":"IN","TotalQuantity":2027,"TotalSales":532739.3100,"IsDistributor":0},
{"Year":2015,"State":"KS","TotalQuantity":940,"TotalSales":216844.0900,"IsDistributor":0},
{"Year":2015,"State":"KY","TotalQuantity":511,"TotalSales":136370.9100,"IsDistributor":0},
{"Year":2015,"State":"LA","TotalQuantity":35,"TotalSales":9926.0500,"IsDistributor":0},
{"Year":2015,"State":"MA","TotalQuantity":4638,"TotalSales":2262278.2147,"IsDistributor":0},
{"Year":2015,"State":"MD","TotalQuantity":4116,"TotalSales":1119331.7664,"IsDistributor":0},
{"Year":2015,"State":"ME","TotalQuantity":1725,"TotalSales":256750.5322,"IsDistributor":0},
{"Year":2015,"State":"MI","TotalQuantity":2837,"TotalSales":785167.4863,"IsDistributor":0},
{"Year":2015,"State":"MN","TotalQuantity":19396,"TotalSales":6560988.9155,"IsDistributor":0},
{"Year":2015,"State":"MO","TotalQuantity":239,"TotalSales":45533.1359,"IsDistributor":0},
{"Year":2015,"State":"MS","TotalQuantity":4,"TotalSales":920.8000,"IsDistributor":0},
{"Year":2015,"State":"MT","TotalQuantity":41,"TotalSales":14209.1000,"IsDistributor":0},
{"Year":2015,"State":"NC","TotalQuantity":5506,"TotalSales":1679007.6369,"IsDistributor":0},
{"Year":2015,"State":"ND","TotalQuantity":5,"TotalSales":883.0000,"IsDistributor":0},
{"Year":2015,"State":"NE","TotalQuantity":49,"TotalSales":12603.4600,"IsDistributor":0},
{"Year":2015,"State":"NH","TotalQuantity":2661,"TotalSales":656975.7190,"IsDistributor":0},
{"Year":2015,"State":"NJ","TotalQuantity":4899,"TotalSales":1857249.7522,"IsDistributor":0},
{"Year":2015,"State":"NM","TotalQuantity":18,"TotalSales":847.1700,"IsDistributor":0},
{"Year":2015,"State":"NV","TotalQuantity":2,"TotalSales":75.0000,"IsDistributor":0},
{"Year":2015,"State":"NY","TotalQuantity":805,"TotalSales":295242.2600,"IsDistributor":0},
{"Year":2015,"State":"OH","TotalQuantity":1712,"TotalSales":533413.1700,"IsDistributor":0},
{"Year":2015,"State":"OR","TotalQuantity":3377,"TotalSales":1164709.0624,"IsDistributor":0},
{"Year":2015,"State":"PA","TotalQuantity":2292,"TotalSales":601890.9000,"IsDistributor":0},
{"Year":2015,"State":"PR","TotalQuantity":2,"TotalSales":115.5000,"IsDistributor":0},
{"Year":2015,"State":"SC","TotalQuantity":2453,"TotalSales":1059821.3817,"IsDistributor":0},
{"Year":2015,"State":"SD","TotalQuantity":250,"TotalSales":84275.1400,"IsDistributor":0},
{"Year":2015,"State":"TN","TotalQuantity":2056,"TotalSales":609389.7013,"IsDistributor":0},
{"Year":2015,"State":"TX","TotalQuantity":1917,"TotalSales":710662.2750,"IsDistributor":0},
{"Year":2015,"State":"UT","TotalQuantity":6416,"TotalSales":1154119.6931,"IsDistributor":0},
{"Year":2015,"State":"VA","TotalQuantity":3021,"TotalSales":479353.2296,"IsDistributor":0},
{"Year":2015,"State":"VT","TotalQuantity":402,"TotalSales":129859.0000,"IsDistributor":0},
{"Year":2015,"State":"WA","TotalQuantity":842,"TotalSales":238343.3901,"IsDistributor":0},
{"Year":2015,"State":"WI","TotalQuantity":12861,"TotalSales":3228575.1303,"IsDistributor":0},
{"Year":2015,"State":"WV","TotalQuantity":1651,"TotalSales":291851.3200,"IsDistributor":0},
{"Year":2015,"State":"WY","TotalQuantity":72,"TotalSales":29821.2600,"IsDistributor":0}]
value property in your JSON is not set. Your tooltip works, because you changed it's format, but you didn't set any values (in Highcharts terms) for points. Try this:
data: data.map(function(el) {
el.value = el.TotalSales;
return el;
});

Cannot get separate views to appear in index.html, and controller is also not working

I'm just starting out with Angular and most of programming in general. I'm trying to make a separate view1.html file appear on my index.html page but it won't, so I'm assuming it's a routing problem. I tried pasting the view1.html content in the body of my index.html to test it and it wasn't showing the controller content either. I'm sure they're simple mistakes but I can't find them. view.html is in a separate folder called views. I only have the javascript in the index.html page for convenience.
index.html
<!DOCTYPE html>
<html lang="en" ng-app='demoApp'>
<head>
<meta charset="UTF-8">
<title>First Angular App</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js"></script>
<body>
<div>
<div ng-view></div>
</div>
<script>
// create module called "demoApp" under the variable name "demoApp"
var demoApp = angular.module('demoApp', []);
// ROUTING
demoApp.config(function ($routeProvider) {
$routeProvider
.when ('/',
{
controller: 'SimpleController',
templateUrl: 'views/view1.html'
})
.when('/view2',
{
controller: 'SimpleController',
templateUrl: 'views/view2.html'
})
.otherwise({ redirectTo: '/' });
});
// CONTROLLERS
demoApp.controller('SimpleController', function ($scope) {
$scope.customers = [
{ name: 'Caleb', city: 'Indianapolis' },
{ name: 'Samantha', city: 'Zionsville' },
{ name: 'Tim', city: 'Palo Alto' }
];
$scope.addCustomer = function () {
$scope.customers.push(
{
name: $scope.newCustomer.name,
city: $scope.newCustomer.city
});
};
}
</script>
</body>
</html>
view1.html
<h2>View 1</h2>
Name:
<input type="text" ng-model="name" />
<ul>
<li ng-repeat="cust in customers"></li>
</ul>
Customer Name:
<input type="text" ng-model="newCustomer.name" />
<br>Customer City:
<input type="text" ng-model="newCustomer.city" />
<br>
<button ng-click="addCustomer()">Add Customer</button>
View 2
</div>
You need to include the script for angular's router.
<head>
<meta charset="UTF-8">
<title>First Angular App</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular-route.min.js"></script>
Also, looks like you're missing a closing </head> tag.
Here's a working version of your HTML file:
<!DOCTYPE html>
<html lang="en" ng-app='demoApp'>
<head>
<meta charset="UTF-8">
<title>First Angular App</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular-route.js"></script>
</head>
<body>
<div>
<div ng-view></div>
</div>
<script>
// create module called "demoApp" under the variable name "demoApp"
var demoApp = angular.module('demoApp', ['ngRoute']);
// ROUTING
demoApp.config(function ($routeProvider) {
$routeProvider
.when ('/',
{
controller: 'SimpleController',
templateUrl: 'view1.html'
})
.when('/view2',
{
controller: 'SimpleController',
templateUrl: 'view2.html'
})
.otherwise({ redirectTo: '/' });
});
// CONTROLLERS
demoApp.controller('SimpleController', function ($scope) {
$scope.customers = [
{ name: 'Caleb', city: 'Indianapolis' },
{ name: 'Samantha', city: 'Zionsville' },
{ name: 'Tim', city: 'Palo Alto' }
];
$scope.newCustomer = { name: "", city: ""};
$scope.addCustomer = function () {
$scope.customers.push(
{
name: $scope.newCustomer.name,
city: $scope.newCustomer.city
});
};
});
</script>
</body>
</html>