I have a GUI that shows live data of little icons moving around based on the data from my postgresql database. When I click on one of the icons, a popup window shows with the data from the database. However, it only shows data on the time the icon was clicked and I want the data displayed to update as the database updates. I could really use some help.
The Popup Window Event
addClickEvent(id, source, publish) {
this.map.on('click', id, function (e) {
let description = ''
let trackId = e.features[0].properties.id
let trackSource = e.features[0].properties.track_source
let trackIdWithSource = trackId + '_' + source
//HELPFUL TIP: This will need to be updated when you bring over an update to base with the previous version
for (const [key, value] of Object.entries(e.features[0].properties)) {
if (isLowerCase(key)) {
}
else { description += key + ': ' + value + '\n' }
}
let trackWindow = document.getElementById("a" + trackIdWithSource);
if (!trackWindow) {
let trackDescription = document.createElement('div')
trackDescription.id = "a" + trackIdWithSource
trackDescription.innerHTML = description;
trackDescription.style.whiteSpace = "pre-wrap"
document.getElementById('root').appendChild(trackDescription)
new WindowModal({ size: { x: 'max-content', y: 200 }, pos: { x: 300, y: 25 }, title: trackIdWithSource + " Info: ", elementSelector: '#a' + trackIdWithSource })
}
trackWindow = document.getElementById("a" + trackIdWithSource);
//let trackContent = trackWindow.getElementsByClassName("WindowModal-content")
if (publish) {
if (!document.getElementById('publish_' + trackIdWithSource)) {
let publishButton = document.createElement('button')
publishButton.innerHTML = "Publish"
publishButton.id = "publish_" + trackIdWithSource
publishButton.onclick = function () {
let url = process.env.REACT_APP_PROTOCOL + '://' + process.env.REACT_APP_PUBLISH_API_HOST + ':' + process.env.REACT_APP_PUBLISH_API_PORT + '/track/' + trackId + '&' + trackSource + '/publish'
fetch(url, { method: 'post' })
.then(function (data) {
return console.log(data.status);
})
}
publishButton.className = "button"
trackWindow.insertBefore(publishButton, trackWindow.children[1])
}
}
});
const popup = new maplibregl.Popup({
closeButton: false,
closeOnClick: false
});
this.map.on("mouseenter", id, function (e) {
const coordinates = e.features[0].geometry.coordinates.slice();
let description = e.features[0].properties.id;
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
}
popup.setLngLat(coordinates)
.setHTML(description)
.addTo(this);
});
this.map.on('mouseleave', id, () => {
this.map.getCanvas().style.cursor = '';
popup.remove();
});
}
Related
I am creating a project that displays the current weather of an area by name search. I fetch the API data from open weather: https://openweathermap.org/current?fbclid=IwAR1SVc9zn9uXaZWLmJA9lYEeZvUc1s_kR68RFadWuIwd8yBjIyJ7zsVMKkE
I have added all the parametres of the API to my code, but if you search some areas, they don't "return" all the weather API parameters. For example, when I search my city's weather at the moment, the parameter " Atmospheric pressure on the sea level" is displaying "undefined" because as Open Weather stated:
Because of that, I don't want the final project to display:
Atmospheric pressure on the sea level: undefined
I want it to return something among the lines of:
Atmospheric pressure on the sea level: not found
As you can see, the data type undefined is replaced with a string.
However, I have found a function here on this site that replaces undefined with "0" and it seems to work because it is marked as "solution". Due to my lack of knowledge tho, I cant get it to work.
The code I have found:
function replaceUndefined(displayWeather){
if(typeof(displayWeather) === "undefined"){
return "0"; // return 0 as replace, and end function execution
}
return displayWeather; // if the above state is false, functions continues and return original value
};
Now, here is my whole JAVASCRIPT code:
let weather = {
apiKey: "χχχχχχχχχχχχχχχ",
fetchWeather: function (city) {
fetch(
"https://api.openweathermap.org/data/2.5/weather?q=" +
city +
"&units=metric&lang=el&appid=" +
this.apiKey
)
.then((response) => {
if (!response.ok) {
alert("No weather found.");
throw new Error("No weather found.");
}
return response.json();
})
.then((data) => this.displayWeather(data));
},
displayWeather: function (data) {
const { name } = data;
const { lon } = data.coord;
const { lat } = data.coord;
const { icon, description } = data.weather[0];
const { temp, humidity } = data.main;
const {temp_min} = data.main;
const {temp_max} = data.main;
const { pressure } = data.main;
const { sea_level } = data.main;
const { speed } = data.wind;
const { deg } = data.wind;
const { sunrise } = data.sys;
const { sunset } = data.sys;
//getting the data from the JSON API file.
document.querySelector(".city").innerText = "Καιρός: " + name;
// (".city") is the class name from the DIV in HTML file.
document.querySelector(".lon").innerText = "Γεωγραφικό μήκος (longitude): " + lon;
document.querySelector(".lat").innerText = "Γεωγραφικό πλάτος (latitude): " + lat;
document.querySelector(".icon").src =
"https://openweathermap.org/img/wn/" + icon + ".png";
document.querySelector(".description").innerText = description;
document.querySelector(".temp").innerText = temp + "°C";
document.querySelector(".temp_min").innerText = "Ελάχιστη θερμοκρασία (αυτην την στιγμή): " + temp_min + "°C";
document.querySelector(".temp_max").innerText = "Μέγιστη θερμοκρασία (αυτην την στιγμή): " + temp_max + "°C";
document.querySelector(".humidity").innerText =
"Υγρασία: " + humidity + "%";
document.querySelector(".pressure").innerText = "Πιέση: " + pressure;
document.querySelector(".sea-pressure").innerText = "Ατμοσφαιρική πίεση στο επίπεδο της θάλασσας: " + sea_level;
document.querySelector(".wind").innerText =
"Ταχύτητα αέρα: " + speed + " km/h";
document.querySelector(".wind-deg").innerText = "Κατεύθυνση του αέρα (degrees): " + deg;
document.querySelector(".sunrise").innerText = "Ανατολή Ήλιου: " + window.moment(sunrise * 1000).format('HH:mm a');
document.querySelector(".sunset").innerText = "Δύση Ήλιου: " + window.moment(sunset * 1000).format('HH:mm a');
document.querySelector(".weather").classList.remove("loading");
document.body.style.backgroundImage =
"url('https://source.unsplash.com/1600x900/?')";
},
search: function () {
this.fetchWeather(document.querySelector(".search-bar").value);
},
};
document.querySelector(".search button").addEventListener("click", function () {
weather.search();
});
document
.querySelector(".search-bar")
.addEventListener("keyup", function (event) {
if (event.key == "Enter") {
weather.search();
}
});
weather.fetchWeather("London");
//Loads weather of London when the page opens
(some texts in the code are in greek because I want the text that is displayed on the page, to be in that language)
Thank you. Please I need solution.
document.querySelector(".sea-pressure").innerText = "Ατμοσφαιρική πίεση στο επίπεδο της θάλασσας: " + sea_level || 'not found';
Or just for hide all the line if data doesn't exist
if(seal_level){
document.querySelector(".sea-pressure").innerText = "Ατμοσφαιρική πίεση στο επίπεδο της θάλασσας: " + sea_level;
}
I implemented blinkid-react-native in react native ios app. blinkid-react-native will give me the ability to scan id's and veirfy the data on them. When i run my code i get json with only the address showing.
Since I can't open the camera to scan an id from the ios simulator. i deployed the app to test flight. i need to debug and see the javascript console.logs. I'm unable to do that from test flight?
I'm not sure about how to debug the issue? Since i can't open the camera on the ios simulator to run BlinkId and go thrugh console.logs.
here is the json the i get
here is BlinkId code
export const scanId = async () => {
console.log('BlinkId*****************');
const licenseKey = Platform.select({
ios:
'**********',
android:
'**********',
});
BlinkIDReactNative.SuccessFrameGrabberRecognizer(mrtdRecognizer);
var blinkIdCombinedRecognizer = new BlinkIDReactNative.BlinkIdCombinedRecognizer();
blinkIdCombinedRecognizer.returnFullDocumentImage = true;
blinkIdCombinedRecognizer.returnFaceImage = true;
const scanningResults = await BlinkIDReactNative.BlinkID.scanWithCamera(
new BlinkIDReactNative.BlinkIdOverlaySettings(),
new BlinkIDReactNative.RecognizerCollection([
blinkIdCombinedRecognizer /*, mrtdSuccessFrameGrabber*/,
]),
licenseKey,
)
.then((result) => handleResult(result))
.catch((e) => e);
return scanningResults;
};
console.log('BlinkId+scanningResults*****************');
console.log(this.scanningResults);
console.log('BlinkId+result1*****************');
console.log(this.result);
const handleResult = (result) => {
function buildResult(result, key) {
if (result && result != -1) {
return key + ': ' + result + '\n';
}
return '';
}
console.log('BlinkId+result2*****************');
console.log(result);
function buildDateResult(result, key) {
if (result) {
return (
key +
': ' +
result.day +
'.' +
result.month +
'.' +
result.year +
'.' +
'\n'
);
}
return '';
}
var localState = {
showFrontImageDocument: false,
resultFrontImageDocument: '',
showBackImageDocument: false,
resultBackImageDocument: '',
resultImageFace: '',
results: '',
showSuccessFrame: false,
successFrame: '',
};
console.log('BlinkId+result3*****************');
console.log(result);
if (result instanceof BlinkIDReactNative.BlinkIdCombinedRecognizerResult) {
let blinkIdResult = result;
console.log('BlinkId+blinkIdResult*****************');
console.log(blinkIdResult);
let resultString =
buildResult(blinkIdResult.firstName, 'First name') +
buildResult(blinkIdResult.lastName, 'Last name') +
buildResult(blinkIdResult.fullName, 'Full name') +
buildResult(blinkIdResult.localizedName, 'Localized name') +
buildResult(
blinkIdResult.additionalNameInformation,
'Additional name info',
) +
buildResult(blinkIdResult.address, 'Address') +
buildResult(
blinkIdResult.additionalAddressInformation,
'Additional address info',
) +
buildResult(blinkIdResult.documentNumber, 'Document number') +
buildResult(
blinkIdResult.documentAdditionalNumber,
'Additional document number',
) +
buildResult(blinkIdResult.sex, 'Sex') +
buildResult(blinkIdResult.issuingAuthority, 'Issuing authority') +
buildResult(blinkIdResult.nationality, 'Nationality') +
buildDateResult(blinkIdResult.dateOfBirth, 'Date of birth') +
buildResult(blinkIdResult.age, 'Age') +
buildDateResult(blinkIdResult.dateOfIssue, 'Date of issue') +
buildDateResult(blinkIdResult.dateOfExpiry, 'Date of expiry') +
buildResult(
blinkIdResult.dateOfExpiryPermanent,
'Date of expiry permanent',
) +
buildResult(blinkIdResult.expired, 'Expired') +
buildResult(blinkIdResult.maritalStatus, 'Martial status') +
buildResult(blinkIdResult.personalIdNumber, 'Personal id number') +
buildResult(blinkIdResult.profession, 'Profession') +
buildResult(blinkIdResult.race, 'Race') +
buildResult(blinkIdResult.religion, 'Religion') +
buildResult(blinkIdResult.residentialStatus, 'Residential status') +
buildResult(blinkIdResult.processingStatus, 'Processing status') +
buildResult(blinkIdResult.recognitionMode, 'Recognition mode');
let licenceInfo = blinkIdResult.driverLicenseDetailedInfo;
if (licenceInfo) {
resultString +=
buildResult(licenceInfo.restrictions, 'Restrictions') +
buildResult(licenceInfo.endorsements, 'Endorsements') +
buildResult(licenceInfo.vehicleClass, 'Vehicle class') +
buildResult(licenceInfo.conditions, 'Conditions');
}
// there are other fields to extract
localState.results += resultString;
// Document image is returned as Base64 encoded JPEG
if (blinkIdResult.fullDocumentFrontImage) {
localState.showFrontImageDocument = true;
localState.resultFrontImageDocument =
'data:image/jpg;base64,' + blinkIdResult.fullDocumentFrontImage;
}
if (blinkIdResult.fullDocumentBackImage) {
localState.showBackImageDocument = true;
localState.resultBackImageDocument =
'data:image/jpg;base64,' + blinkIdResult.fullDocumentBackImage;
}
// Face image is returned as Base64 encoded JPEG
if (blinkIdResult.faceImage) {
localState.showImageFace = true;
localState.resultImageFace =
'data:image/jpg;base64,' + blinkIdResult.faceImage;
}
} else {
throw JSON.stringify(result);
}
console.log('BlinkId+localState*****************');
console.log(localState);
return localState;
};
How to change my code, when I push the button again the information is adding to previous, I need that when I push the button the information updates.
document.querySelector(".city-select").onchange = () => {
let strUser = document.querySelector(".city-select").value;
updateInfo(strUser);
//getWeather()// при селекті
}
function updateInfo(strUser) {
fetch(`http://api.openweathermap.org/data/2.5/weather?q=${strUser}&appid=f3ab273b1163fcf008d6d3ce02f9e86e`)
.then(function (resp) { return resp.json() })
.then(function (data) {
console.log(data);
document.querySelector('.package-name').textContent = data.name;
document.querySelector('.price').innerHTML = Math.round(data.main.temp - 273) + '°';
document.querySelector('.disclaimer').textContent = data.weather[0]['description'];
//https://openweathermap.org/img/wn/02d#2x.png
document.querySelector('.features li').innerHTML = `<img src="https://openweathermap.org/img/wn/${data.weather[0]['icon']}#2x.png">`;
document.querySelector('.button-primary').onclick = () => {
let div = document.createElement('div');
div.innerHTML = 'Wind speed: ' + data.wind.speed + ' km/h' + '<br>'+'Humidity: '+data.main.humidity + '%' + '<br>'+ 'Pressure: ' + data.main.pressure + 'Pa';
document.querySelector('.out').appendChild(div);
}
})
.catch(function () {
// catch any errors
});
}
This is because you used appendChild (https://www.w3schools.com/jsref/met_node_appendchild.asp)
Maybe you should try this instead (if there is already an element) : How to replace DOM element in place using Javascript?
I am trying to understand how the batch rest calls work.
I could not find any simple example on the internet. I have found the examples from https://github.com/andrewconnell/sp-o365-rest but can't run these examples or I have no idea how yet. I am guessing you have to deploy the app to a sharepoint site.
Given that, I am just looking for the simplest example of a add list item and update list item in bulk/batch. Also if anyone knows how I can make the app from that git to run will be really appreciated.
Thanks.
The github project is a add-in project so you need deploy the add-in project, then you can use it.
You could check below script from here.
My test result in this thread
(function () {
jQuery(document).ready(function () {
jQuery("#btnFetchEmployees").click(function () {
addEmployees();
});
});
})();
function addEmployees() {
var employeesAsJson = undefined;
employeesAsJson = [
{
__metadata: {
type: 'SP.Data.EmployeeInfoListItem'
},
Title: 'Geetanjali',
LastName: 'Arora',
Technology: 'SharePoint'
},
{
__metadata: {
type: 'SP.Data.EmployeeInfoListItem'
},
Title: 'Geetika',
LastName: 'Arora',
Technology: 'Graphics'
},
{
__metadata: {
type: 'SP.Data.EmployeeInfoListItem'
},
Title: 'Ashish',
LastName: 'Brajesh',
Technology: 'Oracle'
}
];
addEmployeeInfoBatchRequest(employeesAsJson);
}
function generateUUID() {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16);
});
return uuid;
};
function addEmployeeInfoBatchRequest(employeesAsJson) {
// generate a batch boundary
var batchGuid = generateUUID();
// creating the body
var batchContents = new Array();
var changeSetId = generateUUID();
// get current host
var temp = document.createElement('a');
temp.href = _spPageContextInfo.webAbsoluteUrl;
var host = temp.hostname;
// iterate through each employee
for (var employeeIndex = 0; employeeIndex < employeesAsJson.length; employeeIndex++) {
var employee = employeesAsJson[employeeIndex];
// create the request endpoint
var endpoint = _spPageContextInfo.webAbsoluteUrl
+ '/_api/web/lists/getbytitle(\'EmployeeInfo\')'
+ '/items';
// create the changeset
batchContents.push('--changeset_' + changeSetId);
batchContents.push('Content-Type: application/http');
batchContents.push('Content-Transfer-Encoding: binary');
batchContents.push('');
batchContents.push('POST ' + endpoint + ' HTTP/1.1');
batchContents.push('Content-Type: application/json;odata=verbose');
batchContents.push('');
batchContents.push(JSON.stringify(employee));
batchContents.push('');
}
// END changeset to create data
batchContents.push('--changeset_' + changeSetId + '--');
// batch body
var batchBody = batchContents.join('\r\n');
batchContents = new Array();
// create batch for creating items
batchContents.push('--batch_' + batchGuid);
batchContents.push('Content-Type: multipart/mixed; boundary="changeset_' + changeSetId + '"');
batchContents.push('Content-Length: ' + batchBody.length);
batchContents.push('Content-Transfer-Encoding: binary');
batchContents.push('');
batchContents.push(batchBody);
batchContents.push('');
// create request in batch to get all items after all are created
endpoint = _spPageContextInfo.webAbsoluteUrl
+ '/_api/web/lists/getbytitle(\'EmployeeInfo\')'
+ '/items?$orderby=Title';
batchContents.push('--batch_' + batchGuid);
batchContents.push('Content-Type: application/http');
batchContents.push('Content-Transfer-Encoding: binary');
batchContents.push('');
batchContents.push('GET ' + endpoint + ' HTTP/1.1');
batchContents.push('Accept: application/json;odata=verbose');
batchContents.push('');
batchContents.push('--batch_' + batchGuid + '--');
batchBody = batchContents.join('\r\n');
// create the request endpoint
var endpoint = _spPageContextInfo.webAbsoluteUrl + '/_api/$batch';
var batchRequestHeader = {
'X-RequestDigest': jQuery("#__REQUESTDIGEST").val(),
'Content-Type': 'multipart/mixed; boundary="batch_' + batchGuid + '"'
};
// create request
jQuery.ajax({
url: endpoint,
type: 'POST',
headers: batchRequestHeader,
data: batchBody,
success: function (response) {
var responseInLines = response.split('\n');
$("#tHead").append("<tr><th>First Name</th><th>Last Name</th><th>Technology</th></tr>");
for (var currentLine = 0; currentLine < responseInLines.length; currentLine++) {
try {
var tryParseJson = JSON.parse(responseInLines[currentLine]);
$.each(tryParseJson.d.results, function (index, item) {
$("#tBody").append("<tr><td>" + item.Title + "</td><td>" + item.LastName + "</td><td>" + item.Technology + "</td></tr>");
});
} catch (e) {
}
}
},
fail: function (error) {
}
});
}
I have the following function which populates elements options.
player.onTracksChanged_ = function(event) {
// Update the track lists.
var lists = {
video: document.getElementById('videoTracks'),
audio: document.getElementById('audiotrackButton'),
text: document.getElementById('captionButton')
};
var formatters = {
video: function(track) {
return track.width + 'x' + track.height + ', ' +
track.bandwidth + ' bits/s';
},
audio: function(track) {
return 'language: ' + track.language + ', ' +
track.bandwidth + ' bits/s';
},
text: function(track) {
return 'language: ' + track.language + ' ' +
'(' + track.kind + ')';
}
};
// Clear the old track lists.
Object.keys(lists).forEach(function(type) {
var list = lists[type];
while (list.firstChild) {
list.removeChild(list.firstChild);
}
});
// Populate with the new tracks.
var tracks = player.getTracks();
tracks.sort(function(t1, t2) {
// Sort by language, then by bandwidth.
if (t1.language) {
var ret = t1.language.localeCompare(t2.language);
if (ret) return ret;
}
return t1.bandwidth - t2.bandwidth;
});
tracks.forEach(function(track) {
var list = lists[track.type];
var option = document.createElement('option');
option.textContent = formatters[track.type](track);
option.track = track;
option.value = track.id;
option.selected = track.active;
list.appendChild(option);
});
};
What I am trying to achieve is an if statement based on this which determines if the number of each 'type' of 'track' is greater than or equal to 2, this is what I've got:-
var mediaTracks = player.getTracks();
if (mediaTracks.length >= 2) {
console.log('there are more than 2 tracks');
} else {
console.log('there are less than 2 tracks');
};
When in fact I need to do something more like this:-
var mediaTracksVideo = player.getTracks(video)
var mediaTracksAudio = player.getTracks(audio)
Then do something like:-
if (mediaTracksAudio >= 2) {...
But when I try player.getTracks(audio); the console logs 'audio is not defined'.
Any idea why?
With player.getTracks(audio) you're using the variable audio, which is undefined. You probably want to use player.getTracks('audio'), where 'audio' is a string.