TypeError: this.getISO is not a function - reactjs

I getting typeerror: this.getISO is not a function.
I am trying to implement mapbox API with 3 isochrones plot on it. but i am getting an error that this.getISO is not a function.
map.on("load", function() {
map.addSource("iso", {
type: "geojson",
data: {
type: "FeatureCollection",
features: []
}
});
map.addLayer(
{
id: "isoLayer",
type: "fill",
// Use "iso" as the data source for this layer
source: "iso",
layout: {},
paint: {
// The fill color for the layer is set to a light purple
"fill-color": "#5a3fc0",
"fill-opacity": 0.3
}
},
"poi-label"
);
this.getISO(data => {
map.getSource("iso").setData(data);
});
});
this.map = map;
}
getISO(callback) {
const { duration, lng, lat } = this.state;
fetch(
`https://api.mapbox.com/isochrone/v1/mapbox/driving/${lng},${lat}?
contours_minutes=${duration}&polygons=true&
access_token=pk.eyJ1Ijoiam9uYnN0b3JleSIsImEiOiJjanl5aGFyaWwxaGE3M21ycnhsNGpvYmk2In0.jfxHlg5boDqdiUgf3cco2A`
)
.then(response => response.json())
.then(data => {
callback(data);
});
}

in first-line replace function definition with arrow function and the
like this map.on("load", ()=> {

Use an arrow function () => { instead of function() {.

Related

How to recover SIP js Invitation Object or Session Object in React Js on page refresh

I am implementing Audio/Video call with SIP js and Astrisk server in React JS.I was successful on creating the WebRTC Audio/Video calling. But I am facing an issue with storing the Invitation or Session Object for SIP js. Because Circular JSON data can't be stringed to store.
Assume someone has started calling and the other end got notification of calling and in that case if the page refreshed or reloaded I am unable to recover the call session to take any action(answer/ decline)
/**
* The following code is inside useState and the dependency are handled properly.
* For making it simple and sort I have just copied the required parts. */
const simpleUserDelegate = {
onCallAnswered: (session) => {
console.log(` Call answered`);
if (simpleUser) {
let remoteVideoTrack = simpleUser.getRemoteVideoTrack(session);
if (remoteVideoTrack) {
} else {
setIsAudioCall(true);
}
}
setIsCallAnswered(true);
setIsCallRecieved(false);
localStorage.setItem('isCallRecieved',null);
localStorage.setItem('callerName',null);
localStorage.setItem('callerImage',null);
setIsCallling(false);
},
onCallCreated: (session) => {
setCallSession(session);
console.log(session,` Call created`);
//console.log('session====>',JSON.stringify(session))
// localStorage.setItem('callerUserAgent',JSON.stringify(session._userAgent));
setIsCallling(true);
localStorage.getItem('callerUserAgent')
},
onCallReceived: (invitation) => {
console.log('invitation',invitation);
console.log('invitationSession',invitation.session);
setCallerActiveRoom(invitation._userAgent.options.displayRoomId);
setCallerName(invitation._userAgent.options.displayName);
setCallerImage(invitation._userAgent.options.displayImage);
localStorage.setItem('callerUserAgent',JSON.stringify(invitation.request));
console.log(` Call received`);
// dispatch(setActiveRoomId(invitation._userAgent.options.displayRoomId));
setIsCallRecieved(true);
localStorage.setItem('isCallRecieved',true);
localStorage.setItem('callerName',invitation._userAgent.options.displayName);
localStorage.setItem('callerImage',invitation._userAgent.options.displayImage);
},
onCallHangup: () => {
console.log(` Call hangup`);
setIsCallling(false);
setIsCallRecieved(false);
localStorage.setItem('isCallRecieved',null);
localStorage.setItem('callerName',null);
localStorage.setItem('callerImage',null);
setIsCallAnswered(false);
},
onCallHold: () => {
console.log(` Call hold`);
},
onRegistered: () => {
//console.log('session',session);
console.log(` Call registered`);
},
onUnregistered: () => {
console.log(` Call unregistered`);
},
onServerConnect: () => {
console.log(` server connect`);
},
onServerDisconnect: () => {
console.log(` server dis connect`);
}
};
let simpleUserOptions = {
// traceSip: false,
// logBuiltinEnabled: false,
delegate: simpleUserDelegate,
media: {
constraints: {
audio: true,
video: true
},
local: {
video: document.getElementById('localMedia')
},
remote: {
video: document.getElementById('remoteMedia'),
//audio: remoteAudioRef.current
}
},
userAgentOptions: {
logBuiltinEnabled: true,
logLevel: "debug",
authorizationPassword: password,
authorizationUsername: username,
uri: urI,
noAnswerTimeout : 30,
displayName: name,
displayImage: profileImage,
displayRoomId: `hi${displayRoomId}`
},
};
const simpleUserObj = new Web.SessionManager('wss://pbx.scinner.com:8089/ws', simpleUserOptions);
if(!simpleUserObj.isConnected()){
simpleUserObj
.connect()
.then(() => {
console.log(`${user.username} connected`);
simpleUserObj.register().then(() => {
console.log(`${user.username} registerd`);
}).catch((error) => {
alert("Failed to register.\n" + error);
});
})
.catch((error) => {
alert("Failed to connect.\n" + error);
});
setIsSARegistered(true);
setSimpleUser(simpleUserObj);
setCallerUserAgent
}else{
console.log('isconnected');
setIsSARegistered(true);
}
/**
Set calling
*/
const setCalling = (name, target) => {
simpleUser
.call(target, {
sessionDescriptionHandlerOptions: {
constraints: {
audio: true,
video: true
}
},
inviteWithoutSdp: false
}).then(() => {
console.log(`anon placed a call`);
}).catch((error) => {
console.error(`[${simpleUser.id}] failed to place call`);
console.error(error);
alert("Failed to place call.\n" + error);
});
//setIsCallling(true);
// console.log('isCallling', isCallling)
}
}
const answerCall = () => {
//callSession stored in local state
if (callSession) {
simpleUser.answer(callSession).then(() => {
console.log(`call answered`);
}).catch((error) => {
console.error(`call answered failed`);
console.error(error);
// alert("Failed to place call.\n" + error);
});
}
};

Create and update inside map function

I'm trying to find the right way to create and consequently update inside a map function.
These are the steps I need:
Map function "reads" the array of elements ids
Create new record on "leads_status" table
Using the new record id (from "leads_status") "leads" table is updated using "leads_status.id" as foreign key related to "leads.id_ls"
This is the code I tried.
const [create, { isLoading: isLoadingCreate, error: errorCreate }] = useCreate();
const [record, setRecord] = React.useState(null);
leadsIDS.map((value, index) => {
create('leads_status', {
data: {
id_lead: value,
id_status: 5
}
}, {
onSuccess: ({ id }) => {
setRecord([id, value]);
},
onError: () => {
console.log();
}
});
update('leads', {
id: record[1],
data: {
id_ls: record[0]
}
}, {
enabled: !isLoadingCreate && record !== null
}, {
onSuccess: () => {
console.log(record);
},
onError: error => notify('Error', { type: 'warning' })
})
})
I tried also to put the "update" function inside the "create --> onSuccess" but also there the code is not working as I want.
In "leads_status" table records are always created for each element in "leadsIDS" array but in "leads" table only 1 records is updating.
Where am I wrong?
The useCreate and useUpdate hooks are designed for single actions. If you want to chain several actions, I suggest you use the useDataProvider hook, instead, which lets you manipulate Promises.
const dataProvider = useDataProvider();
const notify = useNotify();
try {
await Promise.all(leadsIDS.map(async (value, index) => {
const { data: leadStatus } = await dataProvider.create('leads_status', {
data: {
id_lead: value,
id_status: 5
}
});
await dataProvider.update('leads', {
id: value,
data: { id_ls: leadStatus.id }
});
}));
} catch (e) {
notify('Error', { type: 'warning' });
}

Cannot read property inside of setTimeOut, how i solve?

I want to get the state inside of setTimeOut
change = () => {
setTimeout(function() {
this.setState({
categories: [...this.state.categories, { time: 20, msg: "msg1", visible:true }]
}) }, 3000);
};
in this this.state.categories i get the next error: "Cannot read property 'categories' of undefined"
That's because the callback you are providing to setTimeout is using the function keyword, which will have its own scope unless you bind it manually. You can fix that cleanly by making the callback an arrow function:
change = () => {
setTimeout(() => {
this.setState({
categories: [...this.state.categories, { time: 20, msg: "msg1", visible:true }]
})
}, 3000);
};
Based on your other comment, if you'd like to manually bind it instead, you can do this:
change = () => {
setTimeout(function () {
this.setState({
categories: [...this.state.categories, { time: 20, msg: "msg1", visible:true }]
})
}.bind(this), 3000);
};
Use arrow function, you missed the this binding. Arrow function will do this for you implicitly.
change = () => {
setTimeout(() => {
this.setState({
categories: [...this.state.categories, { time: 20, msg: "msg1", visible:true }]
}) }, 3000);
};

ReactNative Expo Preloading & Caching Images

I'm new to react-native im trying to preload 10 images at the start of the app I followed expo documentation but
I want to cache images from an external file but it gives me an error [Un Handeled Promise Rejection]
here is my entries.js
export const ENTRIES1 = [
{
title: 'Makeup Artists',
illustration: require('../assets/img/makeup.png')
},
{
title: 'Photographers',
illustration: require('../assets/img/Photographers.png')
},
{
title: 'Wedding Planners',
illustration: require('../assets/img/weddingPlanner.jpg')
},
{
title: 'Wedding Halls',
illustration: require('../assets/img/wedding-Hall.png')
},
{
title: 'Laser & Beauty Centers',
illustration: require('../assets/img/laser.png')
},
]
loadingScreen.js
async componentDidMount() { //Preload Fonts
await Asset.loadAsync(ENTRIES1.illustration),
await Font.loadAsync({
'Roboto': require('../../node_modules/native-base/Fonts/Roboto.ttf'),
'Roboto_medium': require('../../node_modules/native-base/Fonts/Roboto_medium.ttf'),
...Ionicons.font,
});
this.checkIfLoggedIn();
}
what am i doing wrong ? Thanks
Try this :)
function cacheImages(images) {
return images.map(image => {
if (typeof image.illustration === 'string') {
return Image.prefetch(image.illustration);
} else {
return Asset.fromModule(image.illustration).downloadAsync();
}
});
}
async componentDidMount() {
await Asset.cacheImages(ENTRIES1),
await Font.loadAsync({
'Roboto': require('../../node_modules/native-base/Fonts/Roboto.ttf'),
'Roboto_medium': require('../../node_modules/native-base/Fonts/Roboto_medium.ttf'),
...Ionicons.font,
});
this.checkIfLoggedIn();
}

How to trigger handleChange event from inside the function using jquery and react?

I am using fullcalendar-scheduler plugin for following calendar. Currently I have integrated it with react and rails. In order to change the positions of the element I have called the select function from inside viewRender function of fullCalendar instead of render on react. On this case how do we change state when select option is changed and fetch the data again from api?
import React from "react";
import PropTypes from "prop-types";
import axios from "axios";
class TestCalendar extends React.Component {
constructor(props) {
super(props);
this.state = {
cars: [],
events: [],
price: [],
selectDates: [],
startDate: moment(),
endDate: moment().add(3, 'years')
}
}
componentDidMount() {
const headers = {
'Content-Type': 'application/json'
}
axios.get('/api/v1/test_calendars?date_from=' + this.state.startDate.format(), { headers: headers })
.then(res => {
const cars = res.data;
this.setState({ cars });
});
axios.get('/api/v1/test_calendars/events?date_from=' + this.state.startDate.format(), { headers: headers })
.then(res => {
const events = res.data;
this.setState({ events });
});
axios.get('/api/v1/test_calendars/prices?date_from=' + this.state.startDate.format(), { headers: headers })
.then(res => {
const price = res.data;
this.setState({ price });
});
this.updateEvents(this.props.hidePrice);
}
componentDidUpdate() {
console.log('componentDidUpdate');
this.updateEvents(this.props.hidePrice);
console.log(this.state.cars);
}
componentWillUnmount() {
$('#test_calendar').fullCalendar('destroy');
};
handleChange(e) {
debugger;
}
updateEvents(hidePrice) {
function monthSelectList() {
let select = '<div class="Select select-me"><select id="months-tab" class="Select-input">' +
'</select></div>'
return select
}
function getDates(startDate, stopDate) {
var dateArray = [];
while(startDate.format('YYYY-MM-DD') <= stopDate.format('YYYY-MM-DD')) {
dateArray.push(startDate.format('YYYY-MM'));
startDate = startDate.add(1, 'days');
};
return dateArray;
}
$('#test_calendar').fullCalendar('destroy');
$('#test_calendar').fullCalendar({
selectable: false,
defaultView: 'timelineEightDays',
defaultDate: this.props.defaultDate,
views: {
timelineEightDays: {
type: 'timeline',
duration: { days: 8 },
slotDuration: '24:00'
}
},
header: {
left: 'prev',
right: 'next'
},
viewRender: function(view, element) {
let uniqueDates;
$("span:contains('Cars')").empty().append(
monthSelectList()
);
$("#months-tab").on("change", function() {
let index, optionElement, month, year, goToDate;
index = this.selectedIndex;
optionElement = this.childNodes[index];
month = optionElement.getAttribute("data-month");
year = optionElement.getAttribute("data-year");
goToDate = moment([year, (month - 1), 1]).format("YYYY-MM-DD");
$("#test_calendar").fullCalendar('gotoDate', moment(goToDate));
$("#months-tab").find("option[data-month=" + month + "][data-year=" + year + "]").prop("selected", true);
this.handleChange.bind(this)
});
let dates = getDates(moment(), moment().add(3, "years"));
uniqueDates = [...new Set(dates)];
$('#months-tab option').remove();
$.each(uniqueDates, function(i, date) {
$('#months-tab').append($('<option>', {
value: i,
text: moment(date).format('MMMM') + " " + moment(date).format('YYYY'),
'data-month': moment(date).format('MM'),
'data-year': moment(date).format('YYYY'),
}));
});
},
resources: this.state.cars,
resourceRender: function(resourceObj, labelTds, bodyTds) {
labelTds.css('background-image', "url(" + resourceObj.header_image + ")");
labelTds.css('background-size', "160px 88px");
labelTds.css('background-repeat', "no-repeat");
labelTds.css("border-bottom", "1px solid");
labelTds.addClass('resource-render');
labelTds.children().children().addClass("car-name");
},
resourceLabelText: 'Cars',
dayClick: function(date, jsEvent, view, resource) {
},
dayRender: function(date, cell){
cell.addClass('dayrender');
},
select: function(startDate, endDate, jsEvent, view, resource) {
},
events: this.state.events.concat(this.state.price),
eventRender: function(event, element, view){
},
schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives'
});
// Should stay after full component is initialized to avoid fc-unselectable class on select tag for months
$("#months-tab").on("mousedown click", function(event){event.stopPropagation()});
$(".prev-link").on("click", function(event){event.stopPropagation()});
$(".next-link").on("click", function(event){event.stopPropagation()});
}
render () {
return (
<div id='test_calendar'>
</div>
);
}
}
export default TestCalendar;
Here your onchange callback doesn't have the react component context so you cannot change the state without giving access to the proper context. One solution I may quickly suggest is to change your updateEvents function like bellow. I have only kept the changed code.
updateEvents(hidePrice) {
let context = this;
... // your code
$('#test_calendar').fullCalendar({
... // your code
viewRender: function(view, element) {
... // your code
$("#months-tab").on("change", function() {
... // your code
// Call the handleChange with the context.
context.handleChange.bind(context)(this); // edited here
});
... // your code
});
... // your code
}
Then you will be able to call the setState method from the handleChange function.
You must be facing an issue with the this reference, as you are trying to access the method handleChange which is associated with the component this but you are using the normal function for viewRender instead you should use arrow function
see the updated code below, it will solve the issue,
updateEvents(hidePrice) {
$('#test_calendar').fullCalendar({
...
viewRender: (view, element) => { // convert to arrow function so, this (component instance) will be accessible inside.
// store the reference of this (component instance).
const $this = this;
$("#months-tab").on("change", function (e) {
...
// always bind methods in constructor.
$this.handleChange(e);
...
});
},
...
});
}
thanks.

Resources