How to reverse geocode properly with vue2-google-maps - vue.js

This is the response returned by the server :
Using basic reverse geocoding provided by google
<script>
function geocodelatLng(){
var response = [
{
"address": "213 Marlon Forks\nSouth Corineland, HI 81723-1044",
"lat": "10.30431500",
"lng": "123.89035500"
},
{
"address": "1291 Stephania Road\nLake Dorotheastad, TN 82682-76",
"lat": "10.30309100",
"lng": "123.89154500"
},
{
"address": "20330 Schmeler Course Apt. 210\nNorth Ari, NV 70048",
"lat": "10.30356400",
"lng": "123.89964100"
}
] ;
return _.map(response,coords => {
// console.log(arr.index);
var geocoder = new google.maps.Geocoder;
var latLng = {
lat : parseFloat(coords.lat),
lng : parseFloat(coords.lng)
} ;
// for every lat,lng .
// console.log(latLng);
geocoder.geocode({'location': latLng},function (results,status){
if (status === 'OK') {
if (results[0]) {
console.log(results[0].formatted_address);
} else {
window.alert('No results found');
}
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
});
}
this worked and it logs in the console 3 geocoded addresses. But when I use it with this package. It doesn't work this is my code.
geocodedAddress(){
let geocoder = new google.maps.Geocoder();
let theLocations = this.locations ;
return _.map(theLocations, addr => {
var geocoder = new google.maps.Geocoder();
var locationss = {
lat : parseFloat(addr.lat),
lng : parseFloat(addr.lng)
} ;
// var sampleLocation = { lat: 1.39, lng: 103.8 };
return new Promise(function(resolve, reject) {
geocoder.geocode({'location': locationss }, function(results, status){
if (status === 'OK') {
if (results[0]) {
return results[0].formatted_address;
} else {
console.log(status);
window.alert('No results found');
}
}
})
});
});
}
in my template :
<v-list-tile-content>
<v-list-tile-title v-text="geocodedAddress"></v-list-tile-title>
<v-list-tile-sub-title>{{ address.address }}</v-list-tile-sub-title>
</v-list-tile-content>
can you please help me what should i do with my code. Because I'm having a hard time with this .

geocodedAddress is async, you can't use it in HTML template.
You should create a data attribute (for example formatedAddresses) to store result from async request
data() {
return {
locations: [],
formatedAddresses: []
}
},
created() {
// for example, you can call it in created hooks
this.geocodedAddress()
},
methods: {
geocodedAddress() {
var self = this;
let geocoder = new google.maps.Geocoder();
let theLocations = this.locations ;
return Promise.all(_.map(theLocations, addr => {
var geocoder = new google.maps.Geocoder();
var locationss = {
lat : parseFloat(addr.lat),
lng : parseFloat(addr.lng)
} ;
// var sampleLocation = { lat: 1.39, lng: 103.8 };
return new Promise(function(resolve, reject) {
geocoder.geocode({'location': locationss }, function(results, status){
if (status === 'OK') {
if (results[0]) {
return results[0].formatted_address;
} else {
console.log(status);
window.alert('No results found');
return null
}
}
})
});
})).then(data => {
console.log(data)
this.formatedAddresses = data
})
}
}
and in template
<div v-for="address in formatedAddresses" :key="address">{{ address }}</div>

Related

ionic infinite scroll can't show information

I tried to use ionic infinite to load more item,
doRefresh(event) {
console.log('Begin async operation');
setTimeout(() => {
this.nextpage()
console.log("test")
event.target.complete();
}, 2000);
}
nextpage(){
this.datanum = this.datanum+5;
this.sqliteDB.getAttractionsbycondition(this.sql,this.datanum).then(res => {
this.alldata_new = res
this.alldata_new.forEach(element => {
this.geocoder.geocode({ 'address': element.Address }, (results, status) => { //先找到當地的經緯度
let pos;
if (status == google.maps.GeocoderStatus.OK) {
pos = { //目標經緯度
lat: results[0].geometry.location.lat(),
lng: results[0].geometry.location.lng()
};
if(google.maps.geometry.spherical.computeDistanceBetween(new google.maps.LatLng(pos.lat, pos.lng), new google.maps.LatLng(this.exampleLat,this.exampleLng))>=1000){
this.distance = google.maps.geometry.spherical.computeDistanceBetween(new google.maps.LatLng(pos.lat, pos.lng), new google.maps.LatLng(this.exampleLat,this.exampleLng))/1000;
this.distance = Math.round(this.distance);
if(this.distance>this.data.distance){
console.log("too far");
this.alldata_new.splice(this.alldata_new.indexOf(element),1);
}
this.distance = this.distance +"kilometer";
element.distance = this.distance;
}else{
this.distance = google.maps.geometry.spherical.computeDistanceBetween(new google.maps.LatLng(pos.lat, pos.lng), new google.maps.LatLng(this.exampleLat,this.exampleLng));
this.distance = Math.round(this.distance);
if(this.distance/1000>this.data.distance){
console.log("too far");
this.alldata_new.splice(this.alldata_new.indexOf(element),1);
}
this.distance = this.distance +"meter";
element.distance = this.distance;
}
// 四捨五入
// });
}
else{
element.Aname = "failure";
}
});
});
})
console.log(this.alldata+"hello ")
}
Here's the result picture,the problem is It did work and load more items, but the information I want them to show disappeared, but I did check the console.log and the new loaded item did push into my data,so I wonder what could be the problem?

Error integrating Agora.io with nuxt.js Error in created hook: "ReferenceError: AgoraRTC is not defined"

I am integrating Agora Web SDK with nuxt.js.
I have included all the methods I need and my page has the following methods and lifecycle hooks:
methods: {
streamInit(uid, attendeeMode, videoProfile, config) {
let defaultConfig = {
streamID: uid,
audio: true,
video: true,
screen: false
};
switch (attendeeMode) {
case "audio-only":
defaultConfig.video = false;
break;
case "audience":
defaultConfig.video = false;
defaultConfig.audio = false;
break;
default:
case "video":
break;
}
let stream = AgoraRTC.createStream(merge(defaultConfig, config));
stream.setVideoProfile(videoProfile);
return stream;
},
subscribeStreamEvents() {
let rt = this;
rt.client.on("stream-added", function(evt) {
let stream = evt.stream;
console.log("New stream added: " + stream.getId());
console.log("At " + new Date().toLocaleTimeString());
console.log("Subscribe ", stream);
rt.client.subscribe(stream, function(err) {
console.log("Subscribe stream failed", err);
});
});
rt.client.on("peer-leave", function(evt) {
console.log("Peer has left: " + evt.uid);
console.log(new Date().toLocaleTimeString());
console.log(evt);
rt.removeStream(evt.uid);
});
rt.client.on("stream-subscribed", function(evt) {
let stream = evt.stream;
console.log("Got stream-subscribed event");
console.log(new Date().toLocaleTimeString());
console.log("Subscribe remote stream successfully: " + stream.getId());
console.log(evt);
rt.addStream(stream);
});
rt.client.on("stream-removed", function(evt) {
let stream = evt.stream;
console.log("Stream removed: " + stream.getId());
console.log(new Date().toLocaleTimeString());
console.log(evt);
rt.removeStream(stream.getId());
});
},
removeStream(uid) {
this.streamList.map((item, index) => {
if (item.getId() === uid) {
item.close();
let element = document.querySelector("#ag-item-" + uid);
if (element) {
element.parentNode.removeChild(element);
}
let tempList = [...this.streamList];
tempList.splice(index, 1);
this.streamList = tempList;
}
});
},
addStream(stream, push = false) {
let repeatition = this.streamList.some(item => {
return item.getId() === stream.getId();
});
if (repeatition) {
return;
}
if (push) {
this.streamList = this.streamList.concat([stream]);
} else {
this.streamList = [stream].concat(this.streamList);
}
},
handleCamera(e) {
e.currentTarget.classList.toggle("off");
this.localStream.isVideoOn()
? this.localStream.disableVideo()
: this.localStream.enableVideo();
},
handleMic(e) {
e.currentTarget.classList.toggle("off");
this.localStream.isAudioOn()
? this.localStream.disableAudio()
: this.localStream.enableAudio();
},
switchDisplay(e) {
if (
e.currentTarget.classList.contains("disabled") ||
this.streamList.length <= 1
) {
return;
}
if (this.displayMode === "pip") {
this.displayMode = "tile";
} else if (this.displayMode === "tile") {
this.displayMode = "pip";
} else if (this.displayMode === "share") {
// do nothing or alert, tbd
} else {
console.error("Display Mode can only be tile/pip/share");
}
},
hideRemote(e) {
if (
e.currentTarget.classList.contains("disabled") ||
this.streamList.length <= 1
) {
return;
}
let list;
let id = this.streamList[this.streamList.length - 1].getId();
list = Array.from(
document.querySelectorAll(`.ag-item:not(#ag-item-${id})`)
);
list.map(item => {
if (item.style.display !== "none") {
item.style.display = "none";
} else {
item.style.display = "block";
}
});
},
handleExit(e) {
if (e.currentTarget.classList.contains("disabled")) {
return;
}
try {
this.client && this.client.unpublish(this.localStream);
this.localStream && this.localStream.close();
this.client &&
this.client.leave(
() => {
console.log("Client succeed to leave.");
},
() => {
console.log("Client failed to leave.");
}
);
} finally {
this.readyState = false;
this.client = null;
this.localStream = null;
// redirect to index
this.$router.push("/");
}
}
},
created() {
let $ = this;
// init AgoraRTC local client
$.client = AgoraRTC.createClient({ mode: $.transcode });
$.client.init($.appId, () => {
console.log("AgoraRTC client initialized");
$.subscribeStreamEvents();
$.client.join($.appId, $.channel, $.uid, uid => {
console.log("User " + uid + " join channel successfully");
console.log("At " + new Date().toLocaleTimeString());
// create local stream
// It is not recommended to setState in function addStream
$.localStream = this.streamInit(uid, $.attendeeMode, $.videoProfile);
$.localStream.init(
() => {
if ($.attendeeMode !== "audience") {
$.addStream($.localStream, true);
$.client.publish($.localStream, err => {
console.log("Publish local stream error: " + err);
});
}
$.readyState = true;
},
err => {
console.log("getUserMedia failed", err);
$.readyState = true;
}
);
});
});
},
mounted() {
this.$nextTick(() => {
// add listener to control btn group
let canvas = document.querySelector("#ag-canvas");
let btnGroup = document.querySelector(".ag-btn-group");
canvas.addEventListener("mousemove", () => {
if (global._toolbarToggle) {
clearTimeout(global._toolbarToggle);
}
btnGroup.classList.add("active");
global._toolbarToggle = setTimeout(function() {
btnGroup.classList.remove("active");
}, 2000);
});
});
},
beforeUpdate() {
let $ = this;
// rerendering
let canvas = document.querySelector("#ag-canvas");
// pip mode (can only use when less than 4 people in channel)
if ($.displayMode === "pip") {
let no = $.streamList.length;
if (no > 4) {
$.displayMode = "tile";
return;
}
$.streamList.map((item, index) => {
let id = item.getId();
let dom = document.querySelector("#ag-item-" + id);
if (!dom) {
dom = document.createElement("section");
dom.setAttribute("id", "ag-item-" + id);
dom.setAttribute("class", "ag-item");
canvas.appendChild(dom);
item.play("ag-item-" + id);
}
if (index === no - 1) {
dom.setAttribute("style", `grid-area: span 12/span 24/13/25`);
} else {
dom.setAttribute(
"style",
`grid-area: span 3/span 4/${4 + 3 * index}/25;
z-index:1;width:calc(100% - 20px);height:calc(100% - 20px)`
);
}
item.player.resize && item.player.resize();
});
} else if ($.displayMode === "tile") {
// tile mode
let no = $.streamList.length;
$.streamList.map((item, index) => {
let id = item.getId();
let dom = document.querySelector("#ag-item-" + id);
if (!dom) {
dom = document.createElement("section");
dom.setAttribute("id", "ag-item-" + id);
dom.setAttribute("class", "ag-item");
canvas.appendChild(dom);
item.play("ag-item-" + id);
}
dom.setAttribute("style", `grid-area: ${tile_canvas[no][index]}`);
item.player.resize && item.player.resize();
});
} else if ($.displayMode === "share") {
// screen share mode (tbd)
}
},
beforeDestroy () {
this.client && this.client.unpublish(this.localStream);
this.localStream && this.localStream.close();
this.client &&
this.client.leave(
() => {
console.log("Client succeed to leave.");
},
() => {
console.log("Client failed to leave.");
}
);
}
I have installed agora-rtc-sdk from npm.
My plugins/agora.js file looks like this
import Vue from "vue";
import AgoraRTC from 'agora-rtc-sdk';
Vue.use(AgoraRTC);
My nuxt.config.js has plugins declared as:
{
src: "~/plugins/agora.js",
ssr: false
}
The application on loading the page gives AgoraRTC is not defined. How do I add this AgoraRTC to my nuxt.js application?
Agora works only on the client side, fully independent of a server and hence you need to define the mode as client in the nuxt.config.js like this:
{ src: '~/plugins/agora.js', mode: 'client' },

vuejs this is undefined in my eventListner

I've tried to make a google map in vuejs where the value of the center of my map is shown in my view.
For this, I created my marker and tried to update the value with this.marker = map.center.lng(); or this.setMarkerLng(map.center.lng()); inside an event listner of my method Initmap but none of them work. I got the message:
this is undefined
Outside the eventlistener, everything works.
Can you help?
export default {
mounted: function () {
this.initMap();
},
data() {
return {
marker: {
lng : 'latitude',
lat: 'longitude'
}
}
},
methods: {
///google map init
initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 48.587536, lng: 7.751440},
zoom: 13
});
this.setMarkerLat(map.center.lat());
this.setMarkerLng(map.center.lng());
///Listner
autocomplete.addListener('place_changed', function () {
///call method bug
this.setMarkerLat(map.center.lat());
this.setMarkerLng(map.center.lng());
infowindow.close();
this.marker.lat = map.center.lat();
this.marker.lng = map.center.lng();
marker.setVisible(false);
var place = autocomplete.getPlace();
if (!place.geometry) {
window.alert("No details available for input: '" + place.name + "'");
return;
}
// If the place has a geometry, then present it on a map.
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17); // Why 17? Because it looks good.
}
marker.setPosition(place.geometry.location);
marker.setVisible(true);
var address = '';
if (place.address_components) {
address = [
(place.address_components[0] && place.address_components[0].short_name || ''),
(place.address_components[1] && place.address_components[1].short_name || ''),
(place.address_components[2] && place.address_components[2].short_name || '')
].join(' ');
}
},
setMarkerLng: function(lng) {
this.marker.lng = lng;
},
setMarkerLat: function(lat){
this.marker.lat = lat;
}
}
}
Try to use the arrow function ()=> in order to be able to access this scope like :
autocomplete.addListener('place_changed', ()=> {
...
}

Dynamically addTrack to offerer from answerer onnegotiationneeded in webrtc

Is there anyway to notify offerer that non-existing track before just added to get the new stream from the answerer from the code below?
For my current issue now here is that the offerer can add new non-existing track and onnegotiationneeded will be fired and will also be able to createOffer and update media successfully, but when answerer do same process onnegotiationneeded fired normally also from the answerer but no media will be exchanged just because offerer do not have any new track on his end!
I use replaceOrAddTrack(remotePartiID, track, TrackKind) in adding and replacing of tracks
Only the replace works with either ends if it has same track kind from initial connection
_cfg = {
sdpConstraints: {
mandatory: {
OfferToReceiveAudio: true,
OfferToReceiveVideo: true,
VoiceActivityDetection: true,
IceRestart: true
},
optional: []
}
...
};
var channels_wrap = (function() {
return {
...
init: function() {
_cfg.defaultChannel.on('message', (message) => {
if (_cfg.enableLog) {
console.log('Client received message:', message);
}
if (message.type === 'newparticipant') {
var partID = message.from;
var partData = message.fromData;
// Open a new communication channel to the new participant
_cfg.offerChannels[partID] = this.openSignalingChannel(partID);
// Wait for answers (to offers) from the new participant
_cfg.offerChannels[partID].on('message', (msg) => {
if (msg.dest === _cfg.myID) {
if (msg.type === 'reoffer') {
if (_cfg.opc.hasOwnProperty(msg.from)) {
console.log('reoffering')
_cfg.opc[msg.from].negotiationNeeded();
}
} else
if (msg.type === 'answer') {
_cfg.opc[msg.from].peer.setRemoteDescription(new RTCSessionDescription(msg.snDescription),
handlers_wrap.setRemoteDescriptionSuccess,
handlers_wrap.setRemoteDescriptionError);
} else if (msg.type === 'candidate') {
var candidate = new RTCIceCandidate({
sdpMLineIndex: msg.label,
candidate: msg.candidate
});
if (_cfg.enableLog) {
console.log('got ice candidate from ' + msg.from);
}
_cfg.opc[msg.from].peer.addIceCandidate(candidate, handlers_wrap.addIceCandidateSuccess, handlers_wrap.addIceCandidateError);
}
}
});
// Send an offer to the new participant
dialogs_wrap.createOffer(partID, partData);
} else if (message.type === 'bye') {
handlers_wrap.hangup(message.from, message.fromData);
}
});
},
initPrivateChannel: function() {
// Open a private channel (namespace = _cfg.myID) to receive offers
_cfg.privateAnswerChannel = this.openSignalingChannel(_cfg.myID);
// Wait for offers or ice candidates
_cfg.privateAnswerChannel.on('message', (message) => {
if (message.dest === _cfg.myID) {
if (message.type === 'offer') {
var to = message.from;
dialogs_wrap.createAnswer(message.snDescription, _cfg.privateAnswerChannel, to, message.fromData);
} else if (message.type === 'candidate') {
var candidate = new RTCIceCandidate({
sdpMLineIndex: message.label,
candidate: message.candidate
});
_cfg.apc[message.from].peer.addIceCandidate(candidate, handlers_wrap.addIceCandidateSuccess, handlers_wrap.addIceCandidateError);
}
}
});
}
};
})();
var tracks_wrap = (function() {
return {
getParticipants: function(partID = null) {
var participants = {};
if (partID) {
if (_cfg.opc.hasOwnProperty(partID)) {
participants[partID] = {
ID: partID,
type: 'opc'
};
} else
if (_cfg.apc.hasOwnProperty(partID)) {
participants[partID] = {
ID: partID,
type: 'apc'
};
}
} else {
for (let key in _cfg.opc) {
participants[key] = {
ID: key,
type: 'opc'
};
}
for (let key in _cfg.apc) {
participants[key] = {
ID: key,
type: 'apc'
};
}
}
return participants;
},
replaceOrAddTrack: function(remotePartiID, track, TrackKind) {
if (!TrackKind) {
return;
}
var participants = this.getParticipants(remotePartiID);
for (var partiID in participants) {
var peer = null;
if (participants[partiID].type === 'apc' && _cfg.apc.hasOwnProperty(partiID)) {
peer = _cfg.apc[partiID].peer;
} else if (participants[partiID].type === 'opc' && _cfg.opc.hasOwnProperty(partiID)) {
peer = _cfg.opc[partiID].peer;
} else {
continue;
}
var foundTrack = null;
peer.getSenders().forEach(function(rtpSender) {
if (rtpSender.track && TrackKind === rtpSender.track.kind) {
foundTrack = true;
rtpSender.replaceTrack(track);
}
});
if (!foundTrack) {
peer.addTrack(track, _cfg.localStream); //This work only if it is offerrer that add track but not working with answerer even if i tell the offerer to send offer again
}
}
}
};
})();
var dialogs_wrap = (function() {
return {
/**
*
* Send an offer to peer with id partID and metadata as partData
*
*/
createOffer: function(partID, partData) {
if (_cfg.enableLog) {
console.log('Creating offer for peer ' + partID, partData);
}
var opcPeer = new RTCPeerConnection(_cfg.pcConfig, _cfg.peerSetup);
_cfg.opc[partID] = {};
_cfg.opc[partID].peer = opcPeer;
_cfg.opc[partID].peer.onicecandidate = handlers_wrap.handleIceCandidateAnswer(_cfg.offerChannels[partID], partID, partData);
_cfg.opc[partID].peer.ontrack = handlers_wrap.handleRemoteStreamAdded(partID, partData);
_cfg.opc[partID].peer.onremovetrack = handlers_wrap.handleRemoteStreamRemoved(partID, partData);
_cfg.localStream.getTracks().forEach(track => _cfg.opc[partID].peer.addTrack(track, _cfg.localStream));
try {
_cfg.sendChannel[partID] = _cfg.opc[partID].peer.createDataChannel("sendDataChannel", {
reliable: false
});
_cfg.sendChannel[partID].onmessage = handlers_wrap.handleMessage;
if (_cfg.enableLog) {
console.log('Created send data channel');
}
} catch (e) {
alert('Failed to create data channel. \n You need supported RtpDataChannel enabled browser');
console.log('createDataChannel() failed with exception: ', e.message);
}
_cfg.sendChannel[partID].onopen = handlers_wrap.handleSendChannelStateChange(partID);
_cfg.sendChannel[partID].onclose = handlers_wrap.handleSendChannelStateChange(partID);
var onSuccess = (partID, partData) => {
var channel = _cfg.offerChannels[partID];
if (_cfg.enableLog) {
console.log('Sending offering');
}
channel.emit('message', {
snDescription: _cfg.opc[partID].peer.localDescription,
from: _cfg.myID,
fromData: _cfg.myData,
type: 'offer',
dest: partID,
destData: partData
});
}
_cfg.opc[partID].negotiationNeeded = () => {
_cfg.opc[partID].peer.createOffer(_cfg.sdpConstraints).then(offer => {
offer.sdp = sdp_wrap.SDPController(offer.sdp);
return _cfg.opc[partID].peer.setLocalDescription(offer)
})
.then(() => onSuccess(partID, partData)).catch(handlers_wrap.handleCreateOfferError);
}
_cfg.opc[partID].peer.onnegotiationneeded = () => {
_cfg.opc[partID].negotiationNeeded();
}
},
createAnswer: function(snDescription, cnl, to, toData) {
if (_cfg.enableLog) {
console.log('Creating answer for peer ' + to);
}
if (!_cfg.apc.hasOwnProperty(to)) {
var apcPeer = new RTCPeerConnection(_cfg.pcConfig, _cfg.peerSetup);
//apcPeer.setConfiguration(_cfg.pcConfig);
_cfg.apc[to] = {};
_cfg.apc[to].peer = apcPeer;
_cfg.apc[to].peer.onicecandidate = handlers_wrap.handleIceCandidateAnswer(cnl, to, toData);
_cfg.apc[to].peer.ontrack = handlers_wrap.handleRemoteStreamAdded(to, toData);
_cfg.apc[to].peer.onremovetrack = handlers_wrap.handleRemoteStreamRemoved(to, toData);
_cfg.localStream.getTracks().forEach(track => _cfg.apc[to].peer.addTrack(track, _cfg.localStream));
_cfg.apc[to].peer.ondatachannel = handlers_wrap.gotReceiveChannel(to);
}
_cfg.apc[to].peer.setRemoteDescription(new RTCSessionDescription(snDescription), handlers_wrap.setRemoteDescriptionSuccess, handlers_wrap.setRemoteDescriptionError);
var onSuccess = (channel) => {
if (_cfg.enableLog) {
console.log('Sending answering');
}
channel.emit('message', {
snDescription: _cfg.apc[to].peer.localDescription,
from: _cfg.myID,
fromData: _cfg.myData,
type: 'answer',
dest: to,
destData: toData
});
}
_cfg.apc[to].peer.createAnswer().then(function(answer) {
answer.sdp = sdp_wrap.SDPController(answer.sdp);
return _cfg.apc[to].peer.setLocalDescription(answer);
})
.then(() => onSuccess(cnl))
.catch(handlers_wrap.handleCreateAnswerError);
var negotiationNeeded = false;
_cfg.apc[to].peer.onnegotiationneeded = (ev) => {
if (!negotiationNeeded) {
negotiationNeeded = true;
return;
}
//So i tried to create this to tell the offerer to do offer again, offerer do resend offer but nothing seem to happen
cnl.emit('message', {
from: _cfg.myID,
fromData: _cfg.myData,
type: 'reoffer',
dest: to,
destData: toData
});
}
}
};
})();

React Native setItem in storage

I have an forEach loop as follows:
let result_test = [];
forEach(result_to_upload, value => {
if (value.picturepath) {
let body = new FormData();
const photo = {
uri: value.picturepath,
type: 'image/jpeg',
name: value.pictureguid + '.jpg',
};
body.append('image', photo);
let xhr = new XMLHttpRequest();
xhr.open('POST', data_url + "/manager/transport/sync/picture/?pictureguid=" + value.pictureguid);
xhr.onload = (e) => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
result_test.push(
{
"vehicle_id": value.vehicle_id,
"slot_id": value.slot_id,
"area": value.area,
"zone": value.zone,
"aisle": value.aisle,
"side": value.side,
"col": value.col,
"level": value.level,
"position": value.position,
"timestamp": value.timestamp,
"picturepath": value.picturepath,
"pictureguid": value.pictureguid,
"reason": value.reason,
"handled": value.handled,
"uploaded": 1
}
);
}
}
};
xhr.onerror = (e) => console.log('Error');
xhr.send(body);
} else {
result_test.push(
{
"vehicle_id": value.vehicle_id,
"slot_id": value.slot_id,
"area": value.area,
"zone": value.zone,
"aisle": value.aisle,
"side": value.side,
"col": value.col,
"level": value.level,
"position": value.position,
"timestamp": value.timestamp,
"picturepath": value.picturepath,
"pictureguid": value.pictureguid,
"reason": value.reason,
"handled": value.handled,
"uploaded": 1
}
)
}
});
AsyncStorage.setItem('vehicle_slot', JSON.stringify(result_test), () => s_cb())
And result to upload is as follows:
[
{
aisle:""
area:""
category_text: "CT"
col:2
color_text:"Argent"
comment:""
handled:0
level:0
make_text:"Peugeot"
model_text:"208"
pictureguid:"88e6a87b-b48b-4bfd-b42d-92964a34bef6"
picturepath:
"/Users/boris/Library/Developer/CoreSimulator/Devices/E5DB7769-6D3B-4B02-AA8F-CAF1B03AFCB7/data/Containers/Data/Application/DBCFB503-F8E1-42FF-8C2B-260A713AF7BC/Documents/2D840EFA-014C-48C0-8122-53D9A0F4A88E.jpg"
position:0
reason:"ENTER"
reference:""
registration:""
side:"E"
slot_id:2358
tag_text:""
timestamp:"201705021714"
uploaded:0
vehicle_id:1
vin:"123456"
zone:"A"
},
{
aisle:""
area:""
category_text: "CT"
col:2
color_text:"Argent"
comment:""
handled:0
level:0
make_text:"Golf"
model_text:"208"
pictureguid:"88e6a87b-b48b-4bfd-b42d-92964a34bef6"
picturepath:""
position:0
reason:"ENTER"
reference:""
registration:""
side:"B"
slot_id:2358
tag_text:""
timestamp:"201705021714"
uploaded:0
vehicle_id:1
vin:"123456"
zone:"A"
}
]
But for some reason is AsyncStorage.getItem("vehicle_slot").then(json => console.log(JSON.parse(json)) only the second object, the first one is not added to storage.
Any advice?
your XMLHttpRequest is going to run asynchronously. It's perfectly possible that your code might get to the
AsyncStorage.setItem('vehicle_slot', JSON.stringify(result_test), () => s_cb())
before the onload event has occurred, since that only happens when the request is done. You should add the setItem as a callback.
resultToUpload.forEach(result => {
if (result.picturepath) {
// handle stuff here
let xhr = new XMLHttpRequest();
xhr.onload = (e) => {
// handle other stuff
result_test.push(/* data */);
await storeInAsyncStorage(result_test, () => s_cb());
};
} else {
// handle even more stuff
result_test.push(/* different data */);
await storeInAsyncStorage(result_test, () => s_cb());
}
});
function storeInAsyncStorage(data, callback) {
if(callback) {
return AsyncStorage.setItem(JSON.stringify(data), callback);
} else {
return AsyncStorage.setItem(JSON.stringify(data));
}
}
You should also be aware that AsyncStorage.setItem is asynchronous. The item does not get set immediately, and the setItem method returns a promise that resolves when the item is set. Try using await AsyncStorage.setItem if you're not passing it into some other function.