Angular ajax $http cannot post and get in same time - ajax

I'm trying to use MEAN stack store and update a simple angular to do list, I've write a restful api for server.the post record function app.addTask = function(task) working fine if I remove $http.get from html, but once put it back, it stop record the new task.
Can't figure it out why, need your guys help.
Here is the server.js
var express = require('express'),
restful = require('node-restful'),
bodyParser = require('body-Parser'),
methodOverride = require('method-override'),
mongoose = restful.mongoose;
var app = express();
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.use(methodOverride());
mongoose.connect('mongodb://localhost/transTaskDB');
//create new collection
var TaskSchema = mongoose.Schema({
contents: String,
target: String,
color: String,
status: Boolean
});
var Tasks = restful.model('tasks', TaskSchema);
// Tasks.methods(['get', 'post', 'put', 'delete']);
// Tasks.register(app, '/api/tasks');
// ROUTES FOR OUR API
//===============================================
var router = express.Router(); //get an instance of express Router
// middleware to use for all requests
router.use(function(req, res, next) {
// do logging
console.log('Shown when each request made.');
next(); // make sure we go to the next routes and don't stop here
});
//custom filter find the last entry record
//record new task
router.route('/newtask')
.post(function(req, res){
//create a new instance of the task model
var task = new Tasks();
task.contents = req.body.taskContent;
task.target = req.body.taskUser;
task.color = req.body.taskColor;
// task.contents = "have a tea";
// task.target = "tony";
// task.color = "#e74c3c";
task.status = false; //** fasle means the task still open not done
//task.save();
//throw error exception in console
task.save(function(err, tasks) {
if (err)
res.send(err);
res.json(tasks);
});
})
.get(function(req, res){
Tasks.find(function(err, tasks) {
if (err)
res.send(err);
res.json(tasks);
});
});
//REGISTER OUT ROUTES --------
//all of our route will be prefixed with /api
app.use('/api/tasks', router);
app.listen(3000);
console.log('Server is running at port 3000');
html
<!doctype html>
<html lang='en' ng-app='TaskAPP'>
<head>
<meta charset='UTF-8'>
<title>Trans Task</title>
<link rel='stylesheet' href='bower_components/bootstrap-sass/dist/css/bootstrap.min.css' type='text/css'>
<link rel='stylesheet' href='bower_components/bootstrap-sass/dist/css/bootstrap-theme.min.css' type='text/css'>
<style>
body {
background-image: url('images/swirl_pattern.png');
background-repeat: repeat-y repeat-x;
}
.done {text-decoration: line-through; color: #ccc;}
.task-list {list-style: none;}
.published-list {
padding: 10px 40px;
}
.published-list >div {
padding: 20px;
border-radius: 10px;
font-size:20px;
color: white;
}
</style>
</head>
<body>
<div class="container">
<nav class="navbar navbar-inverse" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="#">
<span class="glyphicon glyphicon-tower"></span> Trans Task
</a>
</div>
</nav>
<div ng-controller='taskCtrl as app'>
<form role="form" name='frm2' ng-submit="app.addTask(app.task)">
<div class="form-group">
<label>Task Contains</label>
<input type='text' name='taskInput' class='form-control' ng-model="app.task.taskContent" placeholder="Enter task" required/>
</div>
<div class="form-group">
<!--need find a way to load the registed users from mongodb-->
<!--apply socket.io on each individual user to get realtime task update and update manager the roger response-->
<label>Target assign to</label>
<input type='text' name='taskInput' class='form-control' ng-model="app.task.taskUser" placeholder="Enter name" required/>
</div>
<div class="form-group">
<label>with color</label>
<select ng-model="app.task.taskColor">
<option ng-repeat="col in colors" value="{{col.color}}" >{{col.title}}</option>
</select>
</div>
<button class="btn btn-primary" ng-disabled='frm2.$invalid'>Publish</button>
</form>
<ul class='task-list'>
<li class="published-list" ng-repeat="tsk in app.task">
<div ng-style={'background-color':tsk.color}>
<input type='checkbox' ng-model='tsk.status'>
<span ng-class='{"done":tsk.status}'>{{tsk.contents}}</span>
</div>
</li>
</ul>
<!-- <button class="btn btn-danger" ng-click='clearCompleted()'>Clear Completed</button> -->
</div>
</div>
<script src='bower_components/jquery/dist/jquery.min.js'></script>
<script src='bower_components/angular/angular.min.js'></script>
<script src='bower_components/bootstrap-sass/dist/js/bootstrap.min.js'></script>
<script>
//angular parts
var app = angular.module('TaskAPP',[]);
//ajax sample
app.controller("taskCtrl", function($scope, $http) {
$scope.colors = [
{'title': 'red', 'color': '#e74c3c', 'status':true}, {'title': 'green', 'color': '#2ecc71', 'status':true}, {'title': 'amber', 'color': '#f39c12', 'status':true}
];
//you are the problem
var app = this;
$http.get("http://localhost:3000/api/tasks/newtask")
.success(function(data) {
//the return is the tasks json file
app.task = data;
})
app.addTask = function(task) {
$http.post("http://localhost:3000/api/tasks/newtask", task)
.success(function(data) {
//the return is the tasks json file
app.task = data;
})
}
})
</script>
</body>
</html>

Related

Chart.js 4.0.1 Uncaught ReferenceError: Chart is not defined

I wrote an AJAX Javascript code for my ESP32 datalogger which worked so far using old versions of Chart.js. The website hosted by the ESP32 is not working anylonger if I use a more recent of Chart.js.
The error message I caught is:
Uncaught ReferenceError: Chart is not defined at datalogin.html
The line in the code involved is this one
const myChart = new Chart(ctx, config);
Something in the interpretation seems to occur at a very early stage. But I could not identify what. See code below.
I already tried different Chart.js repository in order to have it working. It had absolutly no influence. I actively looked using different browser regarding this specific problematic and I could not find any way of solving this problem.
Thanks a lot for your support
<!DOCTYPE html>
<html lang="en">
<head>
<title>EFM Meter loggin interface</title>
<link rel="icon" type="image/x-icon" href="lightning.ico">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script type="module" src="https://github.com/cdnjs/cdnjs/blob/master/ajax/libs/Chart.js/4.0.1/chart.js" ></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns#2.0.1/dist/chartjs-adapter-date-fns.bundle.js"></script>
<style>
.jumbotron {
background-color: #000;
color: #fff;
}
</style>
</head>
<body>
<div class="jumbotron text-center">
<h1>Elektrofeldmeter Data Logging Page</h1>
</div>
<div class="container">
<div class="border border-2 m-2">
<div class="row">
<div class="col-sm-12 ">
<div class="container-sm">
<canvas id="myChart" style="" height="152"></canvas>
</div>
</div>
</div>
</div>
<div class="row">
<div class="border border-2 m-2">
<div class="col-sm-12">
<h3> Parameters setup</h3>
</div>
</div>
<div class="border border-2 m-2">
<div class="row">
<div class="col-sm-12">
<label for="customRange1" class="form-label" id="labelPWM">PWM of motor: 190</label>
<input type="range" class="form-range" min="0" max="190" step="1" value="190" onchange="rangeValue(this)" id="customRange1">
</div>
<div class="col-sm-6">
<label for="customRange2" class="form-label" id="labelYmin">Y min: -5000</label>
<input type="range" class="form-range" min="-5000" max="5000" step="1" value="-5000" onchange="rangeY()" id="Ymin">
</div>
<div class="col-sm-6">
<label for="customRange2" class="form-label" id="labelYmax">Y max: +5000 0</label>
<input type="range" class="form-range" min="-5000" max="5000" step="1" value="5000" onchange="rangeY()" id="Ymax">
</div>
<div class="col-sm-12">
<button type="button" class="btn btn-primary" onclick="saveAs()">*.CSV</button>
</div>
</div>
</div>
</div>
</div>
<script>
function rangeValue(element) {
console.log(element.value);
var xhr = new XMLHttpRequest();
xhr.open("GET", "/pwm?value="+element.value, true);
xhr.send();
document.getElementById("labelPWM").innerHTML = "PWM of motor: " + element.value;
};
function rangeY() {
myChart.options.scales.y.max = document.getElementById('Ymax').value;
myChart.options.scales.y.min = document.getElementById('Ymin').value;
myChart.update();
};
function clkOrientation(element) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/clk?value="+element.checked, true);
xhr.send();
}
const animation = { };
const config = {
type: 'line',
data: {
datasets: [{
borderColor: '#fc9905',
borderWidth: 2,
radius: 0,
data: 0
}
]
},
options: {
animation,
interaction: {
intersect: false
},
plugins: {
legend: false
},
scales: {
x: {
type: 'time',
title: {
display: true,
text: 'time',
color: '#000000',
font: {
size: 20
}
},
ticks :
{
color: '#000000',
font: {
size: 12
}
}
},
y: {
type: 'linear',
title: {
display: true,
text: 'Electrical field [V/m] # PWM=190',
color: '#000000',
font: {
size: 20
}
},
ticks :
{
color: '#000000',
font: {
size: 12
}
}
}
},
plugins: {
title: {
display: true,
text: 'Electrical field value [V/m]'
}
}
}
};
Chart.defaults.font.size = 20;
const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, config);
function addData(chart, data) {
for (var i = 0 ; i < data.length; i++){
chart.data.datasets[0].data.push({"x":data[i].x,"y":(data[i].y-32.671)/0.48025});
};
chart.update();
};
function getData() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var txt = this.responseText;
var array = JSON.parse(txt); //Ref: https://www.w3schools.com/js/js_json_parse.asp
addData(myChart,array);
}
};
xhttp.open("GET", "readEFM", true); //Handle readADC server on ESP32
xhttp.send();
};
setInterval(function() {
getData();
}, 5000);
txt = '[{"x":1662921606250,"y":35.71},{"x":1662921606450,"y":35.61},{"x":1662921606650,"y":35.70},{"x":1662921606850,"y":35.74},{"x":1662921607050,"y":35.78},{"x":1662921607250,"y":35.45},{"x":1662921607450,"y":35.65},{"x":1662921607650,"y":35.66},{"x":1662921607850,"y":35.78},{"x":1662921608050,"y":35.76}]';
const myArr = JSON.parse(txt);
addData(myChart,myArr);
myChart.update();
function saveAs(){
let csvContent = "data:text/csv;charset=utf-8,";
for (var i = 0 ; i < myChart.data.datasets[0].data.length; i++){
csvContent+=myChart.data.datasets[0].data[i].x + "," + myChart.data.datasets[0].data[i].y + "\n";
}
var encodedUri = encodeURI(csvContent);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "EFM_log.csv");
document.body.appendChild(link);
link.click();
};
</script>
</body>
</html>

Google recaptcha v3 recaptcha_response is null

i am using google recaptcha v3 in my website ,
here is the code i have added in my html web page in the head:
<script src="https://www.google.com/recaptcha/api.js?render=my public key"></script>
<script>
grecaptcha.ready(function () {
grecaptcha.execute('my public key', { action: 'contact' }).then(function (token) {
var recaptchaResponse = document.getElementById('recaptchaResponse');
ecaptchaResponse.value = token;
});
});
</script>
and i added this in my form :
<input type="hidden" name="recaptcha_response" id="recaptchaResponse">
but when i submit the form and try to see the content of $_POST['recaptcha_response'] with var_dump()
it is just an empty string : string(0) ""
where is the mistake ?
thanks for answers !
i tried lots of changes but everytime i get " token = null " then i try this.. 100% working....
in Your Html
<html>
<head>
</head>
<body>
<form id="contact">
<div class="col-12">
<div class="form-group">
<input type="hidden" name="captcha_token" id="recaptchaResponse" data-sitekey="YOUR-SITE-KEY">
</div>
</div>
<div class="col-12">
<button type="submit" class="btn btn-lg" id="submit-btn">
SUBMIT
</button>
</div>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js?onload=ReCaptchaCallbackV3&render=YOUR-SITE-KEY"></script>
</body>
</html>
after then add in your js file
$(document).ready(function(){
setInterval(function(){
ReCaptchaCallbackV3();
}, 90000);
$(document).on("submit",'#contact',function (e) {
var token = $('[name="g-recaptcha-response"]').val();
console.log(token);
});
});
var ReCaptchaCallbackV3 = function() {
grecaptcha.ready(function () {
grecaptcha.execute('YOUR-SITE-KEY', { action: 'contact' }).then(function (token) {});
});
}
In your original script you have a typo:
var recaptchaResponse = document.getElementById('recaptchaResponse');
ecaptchaResponse.value = token;
Instead of recaptchaResponse, you wrote ecaptchaResponse

displaying laravel show method on vue component

i have a list of movies am trying to display the details of one movie using the show method
here is my component for all movies
<template>
<div>
<el-row :gutter="10">
<el-col :span="6" v-for="movie in movies" v-bind:key="movie">
<el-card shadow="always" :body-style="{ padding: '0px'} ">
<img v-bind:src="movie.cover_photo" class="image" >
<div style="padding: 14px;">
<div class="bottom clearfix">
<router-link :to="{name:'details',params:{id:movie.id}}">{{movie.title}}</router-link>
<router-view></router-view>
<h4>{{ movie.year }}</h4>
<h4>{{ movie.type }}</h4>
</div>
<div class="block">
<el-rate :max="10" ></el-rate>
</div>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
movies: [],
movie:{
id:'',
}
};
},
created(){
this. fetchMovieList();
this.showMovie
},
methods: {
fetchMovieList() {
axios.get('/movies').then(response => {
this.movies = response.data;
})
.catch(error=>console.log(error))
},
showMovie(id){
axios.get('/movies/'+id).then((res)=>{
if(res.data.status==true){
this.movie= res.data.movie;
console.log(res.data.movie)
}else{
alert('No Movie founded with this id')
}
})
.catch((err)=>{alert('error')})
}
}
}
</script>
<style scoped>
.image {
width: 100%;
display: block;
}
</style>
my show method:
public function show($id)
{
$movie=Movie::find($id);
if($movie){
return response()->json(['status'=>true,'movie'=>$movie]);
}else{
return response()->json(['status'=>false]);
}
}
my router on app.js:
const movie=Vue.component('details', require('./components/DetailsComponent.vue').default);
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
const router=new VueRouter({
mode:'history',
routes:[
{
path:'/movie/:id',
name:'movie',
component:movie
},
],
});
const app = new Vue({
el: '#app',
router,
});
when i click on the router link it just changes the url to the id of the movie but it doesnt show the component with details when i hit the show endpoint with a specific id it returns the movie in json format on the browser
I think your variable of v-for conflict with the same variable of data().
You should try another variable name of v-for.
Something like
<el-col :span="6" v-for="value in movies" v-bind:key="movie">
<el-card shadow="always" :body-style="{ padding: '0px'} ">
<img v-bind:src="value.cover_photo" class="image" >
<div style="padding: 14px;">
<div class="bottom clearfix">
<router-link :to="{name:'details',params:{id:value.id}}">{{value.title}}</router-link>
<router-view></router-view>
<h4>{{ value.year }}</h4>
<h4>{{ value.type }}</h4>
</div>
<div class="block">
<el-rate :max="10" ></el-rate>
</div>
</div>
</el-card>
</el-col>
Hope this helps you: Reacting to Params Changes
Regards,

Getting Error in a chatroom that uses socket.io

I am using code as follow
server.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
users = [];
connections = [];
server.listen(process.env.PORT || 3000);
console.log('Server Running...');
app.get('/',function (req, res)
{
res.sendFile(__dirname + '/index.html');
});
io.sockets.on('connection', function(socket){
connections.push(socket);
console.log('Connected to %s sockets connection', connections.length);
// Disconnect
socket.on('disconnect', function (data){
if(!socket.username) return;
users.splice(users.indexOf(socket.username), 1);
updateUsernames();
connections.splice(connections.indexOf(socket), 1);
console.log('Disconnected: %s socket connected', connections.length);
});
//Send Message
socket.on('send message', function(data){
console.log(data);
io.sockets.emit('new message', {msg: data});
});
// New user
socket.on('new user', function(data, callback){
callback(true);
socket.username = data;
console.log(socket.username);
users.push(socket.username);
updateUsernames();
});
function updateUsernames(){
io.sockets.emit('get users', users);
}
});
index.html -> Client
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://immodernafrican.move.pk:3000/socket.io/socket.io.js"></script>
<style type="text/css">
body{
margin-top: 30px;
}
#messageArea{
display: none;
}
</style>
</head>
<body>
<div class="container">
<div id="userFormArea" class="row">
<div class="col-md-12">
<form id="userForm">
<div class="form-group">
<label>Enter Username</label>
<input class="form-control" id="username"/>
<br/>
<input type="submit" class="btn btn-primary " value="Login">
</div>
</form>
</div>
</div>
<div class="row" id="messageArea">
<div class="col-md-4">
<div class="well">
<h3>Online Users</h3>
<ul class="list-group" id="users"></ul>
</div>
</div>
<div class="col-md-8">
<div class="chat" id="chat"></div>
<form id="messageForm">
<div class="form-group">
<label>Enter Message</label>
<textarea class="form-control" id="message"></textarea>
<br/>
<input type="submit" class="btn btn-primary " value="Submit">
</div>
</form>
</div>
</div>
</div>
<script type="text/javascript">
$(function(){
var socket = io.connect('http://immodernafrican.move.pk:3000');
var $messageForm = $('#messageForm');
var $message = $('#message');
var $chat = $('#chat');
var $messageArea = $('#messageArea');
var $userFormArea = $('#userFormArea');
var $userForm = $('#userForm');
var $users = $('#users');
var $username = $('#username');
$messageForm.submit(function(e){
e.preventDefault();
socket.emit('send message', $message.val());
$message.val('');
});
socket.on('new message', function(data){
$chat.append('<div class="well">'+data.msg+'</div>')
});
$userForm.submit(function(e){
e.preventDefault();
socket.emit('new user', $username.val(), function(data){
if(data){
$userFormArea.hide();
$messageArea.show();
}
});
$username.val('');
});
socket.on('get users', function(data){
var html = '';
for(i=0; i<data.length; i++)
{
html += '<li class="list-group-item">'+data[i]+'</li>';
}
users.html(html);
});
});
</script>
</body>
</html>
This is running accurately on localhost but as soon as i upload it to online hosting it gives an error. These are the error i am getting i have seen in console
(index):7 GET http://immodernafrican.move.pk:3000/socket.io/socket.io.js net::ERR_CONNECTION_TIMED_OUT
(index):58 Uncaught ReferenceError: io is not defined
at HTMLDocument.<anonymous> (http://immodernafrican.move.pk/:58:17)
at n (https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js:2:14784)
at Object.fireWith (https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js:2:15553)
at Function.ready (https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js:2:9773)
at HTMLDocument.B (https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js:2:14348)
i have tried to change
var socket = io.connect('http://immodernafrican.move.pk:3000');
to
var socket = io.connect();
but invain can anyone please help me regarding this issue so my chatroom can work
Thanks

Google Maps from JSON File

I'm trying to create a heatmap map with 2 layers using google maps API and heatmaps.js. I'm able to create my map by hard-coding my lat/lon variables, but ultimately I'd like to have my layers fed from JSON files that can easily be refreshed.
Here is my current HTML, which works great.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link href='css/bootstrap.css' rel='stylesheet' type='text/css'></link>
<link href='css/bootstrap-responsive.css' rel='stylesheet' type='text/css'></link>
<script type='text/javascript' src='http://code.jquery.com/jquery-1.8.3.js'></script>
<script type='text/javascript' src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=visualization&.js"></script>
<style type="text/css">
body {
padding-top: 60px;
padding-bottom: 40px;
}
.sidebar-nav {
padding: 9px 0;
}
#media (max-width: 980px) {
/* Enable use of floated navbar text */
.navbar-text.pull-right {
float: none;
padding-left: 5px;
padding-right: 5px;
}
}
</style>
<script>
var map, pointarray, heatmap;
var layer1 = [
{location: new google.maps.LatLng(42.071523,-72.624257), weight:13.747727085},
{location: new google.maps.LatLng(42.37686,-72.46914), weight:6.6332495807},
{location: new google.maps.LatLng(42.40524,-72.528427), weight:5.1961524227},
{location: new google.maps.LatLng(42.383945,-72.511834), weight:1.7320508076},
{location: new google.maps.LatLng(42.433317,-72.114488), weight:5.6568542495}
];
var layer2 = [
{location: new google.maps.LatLng(41.513113,-74.37616), weight:2.4494897428},
{location: new google.maps.LatLng(41.147711,-73.941171), weight:10},
{location: new google.maps.LatLng(41.329376,-74.347207), weight:4.8989794856},
{location: new google.maps.LatLng(41.338977,-73.987248), weight:1.7320508076}
];
function initialize() {
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(38.82, -99.408660),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
pointArray1 = new google.maps.MVCArray(layer1);
pointArray2 = new google.maps.MVCArray(layer2);
heatmap1 = new google.maps.visualization.HeatmapLayer({
data: pointArray1
});
heatmap2 = new google.maps.visualization.HeatmapLayer({
data: pointArray2
});
heatmap1.setMap(map);
heatmap2.setMap(map);
}
//FUNCTION TO CHANGE LAYERS
function changeMap(layerNum) {
if (layerNum == 1) {
updateMap(heatmap1);
}
if (layerNum == 2) {
updateMap(heatmap2);
}
}
//FUNCTION TO UPDATE LAYERS
function updateMap(layer) {
var layerMap = layer.getMap();
if (layerMap) {
layer.setMap(null);
} else {
layer.setMap(map);
}
}
</script>
<link href='css/DT_bootstrap.css' rel='stylesheet' type='text/css'></link>
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="../assets/js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container-fluid">
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="brand" href="#">Test Page</a>
<div class="nav-collapse collapse">
<p class="navbar-text pull-right">
Logged in as ...
</p>
<ul class="nav">
<li class="active">Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
</div>
<body class="container-fluid">
<div class="row">
<div class="span12" style="float: none; margin: 0 auto;">
<body onload="initialize()">
<h3>Test Layers</h3>
<input type='checkbox' name='system_type17' value='1' onclick="changeMap(this.value);" checked="checked" />
<span style="width:100px;display:inline-block;">Layer 1</span>
<input type="checkbox" name="system_type3" value="2" onclick="changeMap(this.value);" checked="checked" />
<span style="width:100px;display:inline-block;">Layer 2</span>
<br><br/>
<div id="map-canvas" style="height: 575px; width: 1000px;"></div>
</body>
</div>
</div>
</body>
</body>
</html>
What I would like to do is replace var layer1 and layer2 with a single JSON file that I would be able to just query, I'm just unsure how to execute something like this. For example, a JSON file that would look something like this:
{
"datapoints": [
{
"lat": "38.1513366000",
"lon": "-97.4341659000",
"weight": "0",
"layer":"1"
},
{
"lat": "38.1513748000",
"lon": "-97.4341125000",
"weight": "0",
"layer":"1"
},
{
"lat": "38.1513938000",
"lon": "-97.4341125000",
"weight": "0",
"layer":"1"
},
{
"lat": "38.1493263000",
"lon": "-97.4339447000",
"weight": "0",
"layer":"1"
},
{
"lat": "38.1493339000",
"lon": "-97.4339447000",
"weight": "0",
"layer":"2"
},
{
"lat": "38.1493377000",
"lon": "-97.4339447000",
"weight": "0",
"layer":"2"
},
{
"lat": "38.1483650000",
"lon": "-97.4358291000",
"weight": "0",
"layer":"2"
},
{
"lat": "38.1484031000",
"lon": "-97.4358062000",
"weight": "0",
"layer":"2"
}
]
}
Updated code per Yehia's suggestions:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link href='css/bootstrap.css' rel='stylesheet' type='text/css'></link>
<link href='css/bootstrap-responsive.css' rel='stylesheet' type='text/css'></link>
<script type='text/javascript' src='js/jquery-1.8.3.js'></script>
<script type='text/javascript' src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=visualization&.js"></script>
<style type="text/css">
body {
padding-top: 60px;
padding-bottom: 40px;
}
.sidebar-nav {
padding: 9px 0;
}
#media (max-width: 980px) {
/* Enable use of floated navbar text */
.navbar-text.pull-right {
float: none;
padding-left: 5px;
padding-right: 5px;
}
}
</style>
<script>
var map, pointarray, heatmap;
/*var layer1 = [
{location: new google.maps.LatLng(42.071523,-72.624257), weight:13.747727085},
{location: new google.maps.LatLng(42.37686,-72.46914), weight:6.6332495807},
{location: new google.maps.LatLng(42.40524,-72.528427), weight:5.1961524227},
{location: new google.maps.LatLng(42.383945,-72.511834), weight:1.7320508076},
{location: new google.maps.LatLng(42.433317,-72.114488), weight:5.6568542495}
];
var layer2 = [
{location: new google.maps.LatLng(41.513113,-74.37616), weight:2.4494897428},
{location: new google.maps.LatLng(41.147711,-73.941171), weight:10},
{location: new google.maps.LatLng(41.329376,-74.347207), weight:4.8989794856},
{location: new google.maps.LatLng(41.338977,-73.987248), weight:1.7320508076}
];*/
function initialize() {
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(38.82, -99.408660),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
}
//FUNCTION TO CHANGE LAYERS
function changeMap(layerNum) {
if (layerNum == 1) {
updateMap(heatmap1);
}
if (layerNum == 2) {
updateMap(heatmap2);
}
}
//FUNCTION TO UPDATE LAYERS
function updateMap(layer) {
var layerMap = layer.getMap();
if (layerMap) {
layer.setMap(null);
} else {
layer.setMap(map);
}
}
</script>
<link href='css/DT_bootstrap.css' rel='stylesheet' type='text/css'></link>
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="../assets/js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container-fluid">
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="brand" href="#">Test Page</a>
<div class="nav-collapse collapse">
<p class="navbar-text pull-right">
Logged in as ...
</p>
<ul class="nav">
<li class="active">Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
</div>
<body class="container-fluid">
<div class="row">
<div class="span12" style="float: none; margin: 0 auto;">
<body onload="initialize()">
<h3>Test Layers</h3>
<input type='checkbox' name='system_type17' value='1' onclick="changeMap(this.value);" checked="checked" />
<span style="width:100px;display:inline-block;">Layer 1</span>
<input type="checkbox" name="system_type3" value="2" onclick="changeMap(this.value);" checked="checked" />
<span style="width:100px;display:inline-block;">Layer 2</span>
<br><br/>
<div id="map-canvas" style="height: 575px; width: 1000px;"></div>
</body>
</div>
</div>
<script type="text/javascript">
$.getJSON("testdata.json").then(function(data) {
$.each(data, function(i,datapoints) {
$.each(datapoints, function(j,datapoint) {
layers.push({
location: new google.maps.LatLng(datapoint.lat, datapoint.lng),
weight: datapoint.weight,
layerID: datapoint.layer
});
});
});
});
<script>
</body>
</body>
</html>
Alright, almost there I think. Thanks so much for your help so far, I know this is painful. Here is my initialize function, I'm still getting Uncaught ReferenceError: layers is not defined
<script type='text/javascript'>
var map, pointarray, heatmap;
function initialize() {
function loadData() {
var layers = [ ];
$.ajax({
url: 'testdata.json',
async: false,
dataType: 'json',
success: function (data) {
for (var i=0; i<data.datapoints.length; i++) {
var datapoint = data.datapoints[i];
if (layers[datapoint.layer]===undefined) {
layers[datapoint.layer] = [];
}
layers[datapoint.layer].push({
location: new google.maps.LatLng(datapoint.lat, datapoint.lon),
weight: datapoint.weight,
layerID: datapoint.layer
});
}
}
});
return layers;
}
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(38.82, -99.408660),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
pointArray1 = new google.maps.MVCArray(layers[1]);
pointArray2 = new google.maps.MVCArray(layers[2]);
heatmap1 = new google.maps.visualization.HeatmapLayer({
data: pointArray1
});
heatmap2 = new google.maps.visualization.HeatmapLayer({
data: pointArray2
});
heatmap1.setMap(map);
heatmap2.setMap(map);
}
//FUNCTION TO CHANGE LAYERS
function changeMap(layerNum) {
if (layerNum == 1) {
updateMap(heatmap1);
}
if (layerNum == 2) {
updateMap(heatmap2);
}
}
//FUNCTION TO UPDATE LAYERS
function updateMap(layer) {
var layerMap = layer.getMap();
if (layerMap) {
layer.setMap(null);
} else {
layer.setMap(map);
}
}
</script>
You'll need a way of reading that JSON and parsing it into the variable(s) you need. Since you're using jQuery, here's a method that would work with the JSON structure you have.
$.getJSON("layers.json").then(function(data) {
$.each(data, function(i,datapoints) {
$.each(datapoints, function(j,datapoint) {
layers.push({
location: new google.maps.LatLng(datapoint.lat, datapoint.lng),
weight: datapoint.weight,
layerID: datapoint.layer
});
});
});
});
Adapt as necessary.
In response to davids12's update, here's a function that returns an array of arrays where each composite array has the datapoints from a certain layer. So, running over your example, layers would have 2 arrays in it (layers[1] and layers[2]) which are basically layer1 and layer2 that you describe in your code (with an additional layerID variable; you could remove it if you wish). This allows you to load much more layers and points just by putting them in the JSON using the format you have now.
function loadData() {
var layers = [ ];
$.ajax({
url: 'j.json',
async: false,
dataType: 'json',
success: function (data) {
for (var i=0; i<data.datapoints.length; i++) {
var datapoint = data.datapoints[i];
if (layers[datapoint.layer]===undefined) {
layers[datapoint.layer] = [];
}
layers[datapoint.layer].push({
location: new google.maps.LatLng(datapoint.lat, datapoint.lng),
weight: datapoint.weight,
layerID: datapoint.layer
});
}
}
});
return layers;
}

Resources