Vue Axios form sending empty data instead of image - vue.js

Alright so I am trying to send image data using JSON but no matter what I do I always end up in sending an empty object... I've tried to console log results but no matter what it just sends empty object
CODE:
<body>
<div id="app">
<div v-if="!image">
<h2>Select an image</h2>
<input type="file" #change="onFileChange" multiple>
</div>
<div v-else>
<div v-for="img in image" class="img_overlay">
<img :src="img" class="img_set"/><br/>
<button #click="removeImage(img)">Remove image</button>
</div>
</div>
</div>
<style>
.img_overlay {
width: 25%;
height: 250px;
float: left;
text-align: center;
}
img {
width: 250px;
height: 200px;
}
</style>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
image: "",
file_data: []
},
methods: {
onFileChange(e) {
var files = e.target.files || e.dataTransfer.files;
if (!files.length)
return;
else if(files.length == 1)
this.createImage(files)
else if(files.length >= 2)
this.createImage(files)
this.file_data = e.target.files;
this.uploadImage(e.target.files);
},
createImage(file) {
var tmp = [];
for(let i = 0; i < file.length; i++) {
var image = new Image();
var reader = new FileReader();
var vm = this;
reader.onload = (e) => {
tmp.push(e.target.result);
};
reader.readAsDataURL(file[i]);
}
vm.image = tmp;
},
removeImage: function (img) {
for(let i = 0; i < this.image.length; i++) {
if(this.image[i] == img) {
this.image.splice(i, 1);
}
}
},
uploadImage: function(x_file) {
const config = {
headers: { 'content-type': 'multipart/form-data' }
}
axios.post('/theme/post_new_image', x_file, config).then(function (response) {
console.log(response);
}).catch(e => { console.log(e); });
}
}
});
</script>
</body>
The result I usualy get is empty object with 5 keys. I've tried to stringify the data and such but I've couldn't find the correct solution for it

You are passing an array of files to your uploadImage function. Try iterating over the array to upload each file:
for (var i = 0, f; f = e.target.files[i]; i++) {
uploadImage(f);
}

Related

how to remove an uploaded images

Here I have tried to remove a uploaded images. Like while if user clicks on any of the images which is uploaded by the user if we click on cross icon it has to remove the images. So below is my code where I have tried and I am able to remove the image but at once multiple images are removing i need to remove only selected images not multiple so how can we do that. all images should have cross icon at the top corner. Please
Vue.config.productionTip = false;
new Vue({
el: '#app',
data() {
return {
files: [],
images: null,
}
},
computed: {
filesNames() {
const fn = []
for (let i = 0; i < this.files.length; ++i) {
fn.push(this.files.item(i).name)
}
return fn
}
},
methods: {
handleFileUploads(event) {
this.files = event.target.files;
this.images = [...this.files].map(URL.createObjectURL);
},
removeImage: function () {
this.images = null
},
submitFile() {
let formData = new FormData();
for (var i = 0; i < this.files.length; i++) {
let file = this.files[i];
formData.append('files[' + i + ']', file);
}
axios.post('/multiple-files', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(function() {
console.log('SUCCESS!!');
})
.catch(function() {
console.log('FAILURE!!');
});
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue#2/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="app">
<h2>Multiple Files</h2>
<hr/>
<label>
<span>Files</span>
<input type="file" multiple #change="handleFileUploads($event)" />
<ul v-if="files.length">
<li v-for="(name, i) in filesNames" :key="i">{{ name }}</li>
</ul>
</label>
<div>
<img v-for="image in images" :src="image" />
<button v-if="images" #click="removeImage()" type="button">×</button>
</div>
<br />
<button #click="submitFiles()">Submit</button>
</div>

Ant design upload cannot upload big file

in the latest version of ant-design-vue, we're no longer able to upload bigger image.
<template>
<a-upload
name="avatar"
list-type="picture-card"
class="avatar-uploader"
:show-upload-list="false"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
:before-upload="beforeUpload"
#change="handleChange"
>
<img v-if="imageUrl" :src="imageUrl" alt="avatar" />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">
Upload
</div>
</div>
</a-upload>
</template>
<script>
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
export default {
data() {
return {
loading: false,
imageUrl: '',
};
},
methods: {
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true;
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl;
this.loading = false;
});
}
},
beforeUpload(file) {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
this.$message.error('You can only upload JPG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('Image must smaller than 2MB!');
}
return isJpgOrPng && isLt2M;
},
},
};
</script>
<style>
.avatar-uploader > .ant-upload {
width: 128px;
height: 128px;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
</style>
it'll return
error POST https://www.mocky.io/v2/5cc8019d300000980a055e76 net::ERR_CONNECTION_RESET will produced after upload file. only file around 10-50 mb is allowed.
i've try by leave action as empty but it'll use base domain with path null as post api.
is there any other way to to leave action as empty so that it can run straight to #change instead stuck in action other than create own api?

Pattern to pass computed data as prop to child component (Promise problem)

I am wondering how to pass a computed variable to a child-component (in a slot). The main component revieves an array of objects by using a post request. What actually happpens is that the variable "Branches" seems to be filled with an empty promise which represents the result-data. So i get a warning because the list-component expects "Branches" to be an array. I tried to delay the rendering of the slot content by using "v-if="Array.isArray(Branches)" or a flag which is set in the computed-method ("syncedBranches") but none of these seems to do it.
How to delay the rendering of that list till "Branches" is a filled array of objects? Shouldnt i use a computed var and pass the data by a getter?
Main Component
<branches-widget-tabs :items="register" :activeItem="activeRegister">
<template #tabbody_0="Branches" >
<h1>Content Register 1</h1>
<branches-widget-list :items="Branches" v-if="syncedBranches"></branches-widget-list>
</template>
<template #tabbody_1="Branches" v-if="Array.isArray(Branches)">
<h1>Content Register 2</h1>
<branches-widget-list :items="Branches" v-if="syncedBranches"></branches-widget-list>
</template>
</branches-widget-tabs>
</div>
</template>
<style>
#branchesWidget {
min-width: 150px;
min-height: 150px;
background-color: #333;
}
#branchesWidget:hover {
background-color: #666;
}
</style>
<script>
import chroma from 'chroma-js';
//console.log('chroma',chroma);
import HUSL from 'hsluv';
//console.log('HUSL',HUSL);
import BranchesWidgetTabs from './BranchesWidgetTabs';
import BranchesWidgetList from './BranchesWidgetList';
const random = function(min, max){
return Math.floor(Math.random() * (max - min + 1)) + min;
};
var generateColors = function(n, startHex = '#ff6000', padding = 0, step = 5, randomSat = true, randomLight = true){
let colors = [];
const baseHex = HUSL.hexToHsluv(startHex);
const baseHue = baseHex[0];
//console.log('baseHue',baseHue);
var degrees = [];
for (let i = 0; i < n; i++) {
degrees.push( 360 / n * i);
}
//console.log('degrees',degrees);
const hues = degrees.map((offset) => {
return (baseHue + offset) % 360;
});
//console.log('hues',hues);
if(randomSat){
var baseSaturation = random(55, 85);
}else{
var baseSaturation = baseHex[1];
}
if(randomLight){
var baseLightness = random(35, 75);
}else{
var baseLightness = baseHex[2];
}
var subs = Math.min(n,Math.max(step,2));
for(let i = 0; i < subs; i++) {
colors.push( HUSL.hsluvToHex([
hues[i],
baseSaturation,
baseLightness
]));
}
console.log('colors',colors);
return chroma.scale(colors).padding(0).mode('lab').colors(n);
};
export default {
name: 'BranchesWidget',
props : [],
data() {
return {
activeRegister : null,
register : [
{
'title' : 'tab1',
}
,
{
'title' : 'tab2',
}
],
rawBranches : null,
syncedBranches : false
}
},
computed: {
Branches : function(){
if(this.rawBranches !== null){
let colorArr = generateColors(this.rawBranches.length);
console.log('colorArr',colorArr);
// Der Liste der Branchen die Farben zuordnen und als "Branches" bereitstellen
var l = [];
for(var i=0;i<this.rawBranches.length;i++){
var c = JSON.parse(JSON.stringify(this.rawBranches[i]));
c.color = colorArr[i];
l.push(c);
}
console.log('compute Branches',l);
this.syncedBranches = true;
return l;
}
console.log('compute Branches',null);
return null;
}
},
components: {
BranchesWidgetTabs,
BranchesWidgetList
},
mounted () {
axios
.post('/assets/get',{ entity : 'industryBranches' })
.then(response => ( this.rawBranches = response.data.data ))
},
created(){
//console.log('created',this.rawData);
},
methods : {
// das die Componenten eine ref mit der Bezeichnung "bwidget" hat, ist die Methode in der Seite mit app.$refs.bwidget.getBranches() erreichbar.
getBranches : function(){
return this.Branches;
}
}
}
</script>
Tabs-Compoent
<template>
<div class="BranchesWidgetTabs">
<div class="menu">
<div class="item" v-for="(item, index) in list">
<div>
<div class="i">
<div v-if="item.active">active</div>
</div>
<div class="title">
{{ item.title }}
</div>
</div>
</div>
<div class="spacer"></div>
</div>
<div class="tabbody" v-for="(item, index) in list">
<div class="content" v-if="item.active">
<slot :name="`tabbody_${index}`"></slot>
</div>
</div>
</div>
</template>
<style>
div.BranchesWidgetTabs {
background-color: yellow;
min-height: 40px;
}
div.BranchesWidgetTabs > div.menu {
display: flex;
flex-direction: row;
}
div.BranchesWidgetTabs > div.menu > .item {
flex: 0 0 auto;
min-width: 10px;
background-color: blue;
color: white;
}
div.BranchesWidgetTabs > div.menu > .item > div {
display: flex;
flex-direction: column;
padding: 0px 20px;
}
div.BranchesWidgetTabs > div.menu > .item:nth-child(odd) > div {
padding-right: 0;
}
div.BranchesWidgetTabs > div.menu > .item > div > div {
flex: 1;
}
div.BranchesWidgetTabs > div.menu > .item > div > div.i {
background-color: darkgrey;
min-height: 10px;
}
div.BranchesWidgetTabs > div.menu > .item > div > div.title {
background-color: pink;
padding: 10px 20px;
}
div.BranchesWidgetTabs > div.menu > .spacer {
flex: 1;
}
</style>
<script>
export default {
name: 'BranchesWidgetTabs',
props : {
items : Array,
activeItem : {
required : true,
validator: function(i){
return typeof i === 'number' || i === null;
}
},
},
data(){
return {
}
},
computed: {
list: function(){
var l = [];
var s = (this.activeItem !== null)? this.activeItem : 0;
for(var i=0;i<this.items.length;i++){
var c = JSON.parse(JSON.stringify(this.items[i]));
if(s === i){
c.active = true;
}else{
c.active = false;
}
l.push(c);
}
return l;
}
},
created(){
console.log('created',this.activeItem);
}
}
</script>
List-Component which revieves items from main component
<template>
<div class="BranchesWidgetList">
Liste
</div>
</template>
<style>
div.BranchesWidgetList {
}
</style>
<script>
export default {
name: 'BranchesWidgetList',
props : {
items : Array
},
data(){
return {
}
},
computed: {
},
created(){
console.log('created BranchesWidgetList',this.items);
}
}
</script>
EDIT:
I got it! Somehow i got misslead by the v-slot-directive. I thought i would have to pass the Branches-Array down to the child-component. But it seems that the context of template and main component is a shared one. So only thing to make sure of is that the async-call for that array is completed by using "Branches.length" in a v-if - no need for an extra variable like "syncedBranches".
Full main component with working code.
<template>
<div id="branchesWidget">
<branches-widget-tabs :items="register" :activeItem="activeRegister">
<template #tabbody_0 v-if="Branches.length">
<h1>Content Register 1</h1>
<branches-widget-list :items="Branches"></branches-widget-list>
</template>
<template #tabbody_1 v-if="Branches.length">
<h1>Content Register 2</h1>
<branches-widget-list :items="Branches"></branches-widget-list>
</template>
</branches-widget-tabs>
</div>
</template>
<style>
#branchesWidget {
min-width: 150px;
min-height: 150px;
background-color: #333;
}
#branchesWidget:hover {
background-color: #666;
}
</style>
<script>
import chroma from 'chroma-js';
//console.log('chroma',chroma);
import HUSL from 'hsluv';
//console.log('HUSL',HUSL);
import BranchesWidgetTabs from './BranchesWidgetTabs';
import BranchesWidgetList from './BranchesWidgetList';
const random = function(min, max){
return Math.floor(Math.random() * (max - min + 1)) + min;
};
var generateColors = function(n, startHex = '#ff6000', padding = 0, step = 5, randomSat = true, randomLight = true){
let colors = [];
const baseHex = HUSL.hexToHsluv(startHex);
const baseHue = baseHex[0];
//console.log('baseHue',baseHue);
var degrees = [];
for (let i = 0; i < n; i++) {
degrees.push( 360 / n * i);
}
//console.log('degrees',degrees);
const hues = degrees.map((offset) => {
return (baseHue + offset) % 360;
});
//console.log('hues',hues);
if(randomSat){
var baseSaturation = random(55, 85);
}else{
var baseSaturation = baseHex[1];
}
if(randomLight){
var baseLightness = random(35, 75);
}else{
var baseLightness = baseHex[2];
}
var subs = Math.min(n,Math.max(step,2));
for(let i = 0; i < subs; i++) {
colors.push( HUSL.hsluvToHex([
hues[i],
baseSaturation,
baseLightness
]));
}
console.log('colors',colors);
return chroma.scale(colors).padding(0).mode('lab').colors(n);
};
export default {
name: 'BranchesWidget',
props : [],
data() {
return {
activeRegister : null,
register : [
{
'title' : 'tab1',
}
,
{
'title' : 'tab2',
}
],
rawBranches : null
}
},
computed: {
Branches : function(){
var l = [];
if(this.rawBranches !== null){
let colorArr = generateColors(this.rawBranches.length);
//console.log('colorArr',colorArr);
// Der Liste der Branchen die Farben zuordnen und als "Branches" bereitstellen
for(var i=0;i<this.rawBranches.length;i++){
var c = JSON.parse(JSON.stringify(this.rawBranches[i]));
c.color = colorArr[i];
l.push(c);
}
}
console.log('compute Branches',l);
return l;
}
},
components: {
BranchesWidgetTabs,
BranchesWidgetList
},
mounted () {
axios
.post('/assets/get',{ entity : 'industryBranches' })
.then(response => ( this.rawBranches = response.data.data ))
},
created(){
//console.log('created',this.rawData);
},
methods : {
getBranches : function(){
return this.Branches;
}
}
}
</script>
I got it! Somehow i got misslead by the v-slot-directive. I thought i would have to pass the Branches-Array down to the child-component. But it seems that the context of template and main component is a shared one. So only thing to make sure of is that the async-call for that array is completed by using "Branches.length" in a v-if - no need for an extra variable like "syncedBranches".
To pass the variable "Branches" as a prop there is no need for passing it in as a scoped variable. That is only needed if you want to access those data between the template tags in the main component file.
Full main component with working code.
<template>
<div id="branchesWidget">
<branches-widget-tabs :items="register" :activeItem="activeRegister">
<template #tabbody_0 v-if="Branches.length">
<h1>Content Register 1</h1>
<branches-widget-list :items="Branches"></branches-widget-list>
</template>
<template #tabbody_1 v-if="Branches.length">
<h1>Content Register 2</h1>
<branches-widget-list :items="Branches"></branches-widget-list>
</template>
</branches-widget-tabs>
</div>
</template>
<style>
#branchesWidget {
min-width: 150px;
min-height: 150px;
background-color: #333;
}
#branchesWidget:hover {
background-color: #666;
}
</style>
<script>
import chroma from 'chroma-js';
//console.log('chroma',chroma);
import HUSL from 'hsluv';
//console.log('HUSL',HUSL);
import BranchesWidgetTabs from './BranchesWidgetTabs';
import BranchesWidgetList from './BranchesWidgetList';
const random = function(min, max){
return Math.floor(Math.random() * (max - min + 1)) + min;
};
var generateColors = function(n, startHex = '#ff6000', padding = 0, step = 5, randomSat = true, randomLight = true){
let colors = [];
const baseHex = HUSL.hexToHsluv(startHex);
const baseHue = baseHex[0];
//console.log('baseHue',baseHue);
var degrees = [];
for (let i = 0; i < n; i++) {
degrees.push( 360 / n * i);
}
//console.log('degrees',degrees);
const hues = degrees.map((offset) => {
return (baseHue + offset) % 360;
});
//console.log('hues',hues);
if(randomSat){
var baseSaturation = random(55, 85);
}else{
var baseSaturation = baseHex[1];
}
if(randomLight){
var baseLightness = random(35, 75);
}else{
var baseLightness = baseHex[2];
}
var subs = Math.min(n,Math.max(step,2));
for(let i = 0; i < subs; i++) {
colors.push( HUSL.hsluvToHex([
hues[i],
baseSaturation,
baseLightness
]));
}
console.log('colors',colors);
return chroma.scale(colors).padding(0).mode('lab').colors(n);
};
export default {
name: 'BranchesWidget',
props : [],
data() {
return {
activeRegister : null,
register : [
{
'title' : 'tab1',
}
,
{
'title' : 'tab2',
}
],
rawBranches : null
}
},
computed: {
Branches : function(){
var l = [];
if(this.rawBranches !== null){
let colorArr = generateColors(this.rawBranches.length);
//console.log('colorArr',colorArr);
// Der Liste der Branchen die Farben zuordnen und als "Branches" bereitstellen
for(var i=0;i<this.rawBranches.length;i++){
var c = JSON.parse(JSON.stringify(this.rawBranches[i]));
c.color = colorArr[i];
l.push(c);
}
}
console.log('compute Branches',l);
return l;
}
},
components: {
BranchesWidgetTabs,
BranchesWidgetList
},
mounted () {
axios
.post('/assets/get',{ entity : 'industryBranches' })
.then(response => ( this.rawBranches = response.data.data ))
},
created(){
//console.log('created',this.rawData);
},
methods : {
getBranches : function(){
return this.Branches;
}
}
}
</script>

How can I make my WebRTC is working properly

Now I am building a video call site with WebRTC. But it recognize camera and ask to allow camera.
When I allow camera it shows nothing.
I will write down my code here.
<body onload="init()">
<div class="row">
<div class="col-8">
<form action="#">
<h5>Current Room ID: <span id="curr_room_id"></span><br/></h5>
<input id="new_room_id" name="room" type="text" placeholder="Enter a room id to connect..." style="padding: 5px"/>
<input type="submit" id="connect" value="Connect" />
</form>
<input id="call" type="submit" value="Call" disabled="true"/>
<input id="end" type="submit" value="End Call"disabled="true"/>
</div>
<div class="col-4" id="google_translate_element"></div>
</div>
<h1>local</h1>
<video id="local_video" width="400px" style="border: 1px solid black;"></video>
<h1>remote</h1>
<video id="remote_video" width="400px" style="border: 1px solid black;"></video>
<script src="/socket.io/socket.io.js"></script>
<script src="../scripts/video-client.js"></script>
<script src="../scripts/video-room.js"></script>
<script>
function init() {
console.log("document loaded");
call.removeAttribute("disabled");
call.addEventListener("click", function(){
createPeerConnection();
call.setAttribute("disabled", true);
end.removeAttribute("disabled");
});
end.addEventListener("click", function() {
// change rooms
end.setAttribute("disabled", true);
call.removeAttribute("disabled");
});
}
</script>
</body>
I think it is because of not showing video stream to webview. But i didn't find nothing. Please tell me.
And here is video-client.js
console.log("loaded");
var socket = io();
var local = document.getElementById("local_video");
var remote = document.getElementById("remote_video");
var call = document.getElementById("call");
var end = document.getElementById("end");
var room_id = document.getElementById("curr_room_id");
var localStream = null, remoteStream = null;
var config = {'iceServers' : [{'url' : 'stun:stun.l.google.com:19302'}]};
var pc;
/////////////////////////////////
function createPeerConnection() {
try {
pc = new RTCPeerConnection(config);
pc.onicecandidate = handleIceCandidate;
pc.onaddstream = handleRemoteStreamAdded;
pc.onremovestream = handleRemoteStreamRemoved;
pc.onnegotiationneeded = handleNegotiationNeeded;
getUserMedia(displayLocalVideo);
pc.addStream(localStream);
console.log("Created RTCPeerConnection");
} catch (e) {
console.log("Failed to create PeerConnection: " + e.message);
return;
}
}
function handleIceCandidate(event) {
console.log("handleIceCandidate event: " + event);
if(event.candidate) {
sendMessage(JSON.stringify({'candidate': evt.candidate}));
} else {
consolel.log("End of ice candidates");
}
}
function handleRemoteStreamAdded(event) {
console.log("Remote stream added");
displayRemoteVideo(event.stream);
call.setAttribute("disabled", true);
end.removeAttribute("disabled");
}
function handleRemoteStreamRemoved(event) {
console.log("Remote stream removed: " + event);
end.setAttribute("disabled", true);
call.removeAttribute("disabled");
local.src = "";
remote.src = "";
}
function handleNegotiationNeeded() {
pc.createOffer(localDescCreated, logError);
}
function localDescCreated(desc) {
pc.setLocalDescription(desc, function() {
sendMessage(JSON.stringify({'sdp': pc.localDescription}));
}, logError);
}
call.onclick(function(){
createPeerConnection();
});
/////////////////////////////////
function getUserMedia(callback) {
navigator.mediaDevices.getUserMedia({video: true, audio: false}).then(
function(stream) {
callback(stream);
return stream;
}).catch(logError);
}
function displayLocalVideo(stream) {
localStream = stream;
local.src = window.URL.createObjectURL(stream);
local.play();
}
function displayRemoteVideo(stream) {
remoteStream = stream;
remote.src = window.URL.createObjectURL(stream);
remote.play();
}
function logError(error) {
console.log(error);
}
function sendMessage(message) {
socket.emit("message", message);
}
/////// receiving stream //////////
socket.on("message", function(evt){
if(!pc)
createPeerConnection();
var message = JSON.parse(evt.data);
if(message.sdp) {
pc.setRemoteDescription(new RTCSessionDescription(), function() {
if(pc.remoteDescription.type == 'offer')
pc.createAnswer(localDescCreated, logError);
}, logError);
} else {
pc.addIceCandidate(new RTCIceCandidate(message.candidate));
}
});
I think call.onclick() has to work properly for video streaming but it does not also.
You are not seeing your video because you are not using the stream that getUserMedia returns. You need to attach that stream to the video.

Google maps api departureTime in directionsService

I'm trying to set a departureTime options but does not seem to work.
in the example the road ss38 between Bormio and Prato allo Stelvio this season is closed.
Starting in August, I expect that you are using this road and not the one that currently offers through the Swiss.
thanks
Here's my code:
function initialize() {
map = new google.maps.Map(document.getElementById("map"), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
position: google.maps.ControlPosition.TOP_CENTER
},
streetViewControl: true,
streetViewControlOptions: {
position: google.maps.ControlPosition.TOP_LEFT
},
zoomControl: true,
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_TOP
}
});
map.setZoom(10); // This will trigger a zoom_changed on the map
map.setCenter(new google.maps.LatLng(46.6199, 10.5924));
directionsDisplay.setMap(map);
geocoderService = new google.maps.Geocoder();
directionsService = new google.maps.DirectionsService;
var marker = new google.maps.Marker({
position: new google.maps.LatLng(46.6199, 10.5924),
map: map,
draggable: true
});
var marker2 = new google.maps.Marker({
position: new google.maps.LatLng(46.4693, 10.3731),
map: map,
draggable: true
});
calcolapercorso(tipodipercorso);
}
function calcolapercorso(tipodipercorso) {
var request = {
origin: new google.maps.LatLng(46.6199, 10.5924),
destination: new google.maps.LatLng(46.4693, 10.3731),
optimizeWaypoints: false,
avoidHighways: true,
region: "IT",
travelMode: google.maps.TravelMode.DRIVING,
drivingOptions: {
departureTime: new Date('2016-08-11T00:00:00'),
trafficModel: google.maps.TrafficModel.PESSIMISTIC
}
};
//request.travelMode = google.maps.DirectionsTravelMode.DRIVING;
request.unitSystem = google.maps.UnitSystem.METRIC;
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
var polyLine = {
strokeColor: "#2B8B3F",
strokeOpacity: 1,
strokeWeight: 4,
};
directionsDisplay.setOptions({
polylineOptions: polyLine,
suppressMarkers: true
});
directionsDisplay.setDirections(response);
} else if (status == google.maps.DirectionsStatus.ZERO_RESULTS) {
alert("Could not find a route between these points");
} else {
alert("Directions request failed");
}
});
}
I figured out that the departureTime option does not work when you set any waypoints (at least in Google Maps Javascript API. I didn't confirm RestAPI).
Without waypoints, it worked.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
#map_canvas {
width: 600px;
height: 400px;
border: 1px solid gray;
float: left;
}
#direction_panel {
width: 250px;
height: 400px;
border: 1px solid gray;
overflow-y:scroll;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?language=en&v=3.exp&client=[YOUR_CLIENT_ID]"></script>
<script>
function initialize() {
var mapDiv = document.getElementById("map_canvas");
var map = new google.maps.Map(mapDiv, {
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var form = document.getElementById("form");
google.maps.event.addDomListener(form, "submit", function(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.cancelBubble = true;
event.returnValue = false;
}
map.set("traffic", google.maps.TrafficModel[this.trafficModel.value]);
});
var directionsService = new google.maps.DirectionsService();
map.set("directionsService", directionsService);
var panelDiv = document.getElementById("direction_panel");
var directionsRenderer = new google.maps.DirectionsRenderer({
map: map,
panel: panelDiv
});
map.set("directionsRenderer", directionsRenderer);
map.addListener("traffic_changed", onTrafficModelChanged);
}
function onTrafficModelChanged() {
var map = this;
var departureDateTime = document.getElementById("departureTime").value;
var directionsService = map.get("directionsService");
var directionsRenderer = map.get("directionsRenderer");
var trafficModel = map.get("traffic");
var request = {
origin: "<YOUR ORIGIN>",
destination: "<YOUR DESTINATION>",
travelMode: google.maps.TravelMode.DRIVING,
drivingOptions: {
departureTime: new Date(departureDateTime),
trafficModel: trafficModel
}
};
directionsService.route(request, function(result, status) {
if (status != google.maps.DirectionsStatus.OK) {
alert(status);
return;
}
directionsRenderer.setDirections(result);
});
}
google.maps.event.addDomListener(window, "load", initialize);
</script>
</head>
<body>
<div id="frame">
<div id="map_canvas"></div>
<div id="direction_panel"></div>
</div>
<form id="form">
Departure Time: <input type="text" id="departureTime" size=40 value="2016/01/25 21:00 PST"><br>
<input type="radio" name="trafficModel" value="OPTIMISTIC">Optimistic
<input type="radio" name="trafficModel" value="BEST_GUESS" checked>BEST_GUESS
<input type="radio" name="trafficModel" value="PESSIMISTIC">PESSIMISTIC
<input type="submit" value="Search">
</form>
</body>
</html>