I am working on an application where I have created service js which I need to consume in different components of vue3. Here is my service code
const base_url = "https://localhost:7005/";
var apiObject = {
data: function() {
return {
response : undefined
};
},
methods: {
fetchContent: function(apiEndpoint) {
axios
.get(`${base_url}${apiEndpoint}`)
.then(res => {
this.response = res
})
.catch(e => {
this.errors.push(e);
});
}
}
};
Here is my component code. It is not working it gives me the error show in image below
<script>
import {fetchContent} from "../service/apiService";
export default {
data() {
return {
// url_base: "https://localhost:7005/api/weather/",
weather: undefined,
error : false,
errormessage : "",
searchHistory : []
};
},
methods : {
async fetchWeather(e) {
if (e.key == "Enter" && this.query) {
let {response} =await fetchContent(`api/weather/forecast?city=${query}`) //get(query,`${weather_url}forecast?city=`); //await axios.get(`${this.url_base}forecast?city=${this.query}`);
this.setResults(response.data);
}else if (e.key == "Enter" && !this.query){
this.error = true;
this.errormessage = 'Please enter name to search!';
}
},
setResults(res) {
if(res.isSuccessful === true){
this.error = false;
this.weather = res.response;
this.saveData(res.response)
}else{
this.weather = undefined;
this.errormessage = res.response;
this.error = true;
}
},
saveData(res){
this.searchHistory = JSON.parse(localStorage.getItem("SearchHistory"));
if(this.searchHistory == null){this.searchHistory = [];}
res.forEach(x => {
this.searchHistory.push(x);
});
localStorage.setItem("SearchHistory",JSON.stringify(this.searchHistory));
}
},
};
</script>
Image
I'm having trouble changing the prop: 'rate' to change the speed of the audio being played.
I'm using expo-av (https://docs.expo.dev/versions/latest/sdk/av/).
Here's my code:
import {Text, View, Alert } from 'react-native'
import * as MediaLibrary from 'expo-media-library';
import { DataProvider } from 'recyclerlistview';
import {Audio} from 'expo-av';
import { play, pause, resume, playNext } from "../misc/AudioController";
export const AudioContext = createContext()
export class AudioProvider extends Component {
constructor(props) {
super(props);
this.state = {
audioFiles: [],
permissionError: false,
dataProvider: new DataProvider((r1, r2) => r1 !== r2),
playbackObj: null,
soundObj: null,
currentAudio: {},
isPlaying: false,
currentAudioIndex: null,
playbackPosition: null,
playbackDuration: null,
rate: 2.0,
};
this.totalAudioCount = 0;
}
permissionAlert = () => {
Alert.alert("Permission Required", "This app needs to read audio files", [
{ text: "I am ready", onPress: () => this.getPermission() },
{
text: "cancel",
onPress: () => this.permissionAlert(),
},
]);
};
getAudioFiles = async () => {
const { dataProvider, audioFiles } = this.state;
let media = await MediaLibrary.getAssetsAsync({
mediaType: "audio",
});
media = await MediaLibrary.getAssetsAsync({
mediaType: "audio",
first: media.totalCount,
});
this.totalAudioCount = media.totalCount;
this.setState({
...this.state,
dataProvider: dataProvider.cloneWithRows([
...audioFiles,
...media.assets,
]),
audioFiles: [...audioFiles, ...media.assets],
});
};
loadPreviousAudio = async () => {
let previousAudio = await AsyncStorageLib.getItem("previousAudio");
let currentAudio;
let currentAudioIndex;
if (previousAudio === null) {
currentAudio = this.state.audioFiles[0];
currentAudioIndex = 0;
} else {
previousAudio = JSON.parse(previousAudio);
currentAudio = previousAudio.audio;
currentAudioIndex = previousAudio.index;
}
this.setState({ ...this.state, currentAudio, currentAudio });
};
getPermission = async () => {
// {
// "canAskAgain": true,
// "expires": "never",
// "granted": false,
// "status": "undetermined",
// }
const permission = await MediaLibrary.getPermissionsAsync();
if (permission.granted) {
this.getAudioFiles();
}
if (!permission.canAskAgain && !permission.granted) {
this.setState({ ...this.state, permissionError: true });
}
if (!permission.granted && permission.canAskAgain) {
const { status, canAskAgain } =
await MediaLibrary.requestPermissionsAsync();
if (status === "denied" && canAskAgain) {
this.permissionAlert();
}
if (status === "granted") {
this.getAudioFiles();
}
if (status === "denied" && !canAskAgain) {
this.setState({ ...this.state, permissionError: true });
}
}
};
onPlaybackStatusUpdate = async (playbackStatus) => {
console.log("hier");
if (playbackStatus.isLoaded && playbackStatus.isPlaying) {
this.updateState(this, {
playbackPosition: playbackStatus.positionMillis,
playbackDuration: playbackStatus.durationMillis,
});
}
if (playbackStatus.didJustFinish) {
const nextAudioIndex = this.state.currentAudioIndex + 1;
if (nextAudioIndex >= this.totalAudioCount) {
this.state.playbackObj.unloadAsync();
this.updateState(this, {
soundObj: null,
currentAudio: this.state.audioFiles[0],
isPlaying: false,
currentAudioIndex: 0,
playbackPosition: null,
playbackDuration: null,
});
}
const audio = this.state.audioFiles[nextAudioIndex];
const status = await playNext(this.state.playbackObj, audio.uri);
this.updateState(this, {
soundObj: status,
currentAudio: audio,
isPlaying: true,
currentAudioIndex: nextAudioIndex,
});
}
};
componentDidMount() {
this.getPermission();
if (this.state.playbackObj === null) {
this.setState({ ...this.state, playbackObj: new Audio.Sound(), });
}
}
updateState = (prevState, newState = {}) => {
this.setState({ ...prevState, ...newState });
};
render() {
const {
audioFiles,
dataProvider,
permissionError,
playbackObj,
soundObj,
currentAudio,
isPlaying,
currentAudioIndex,
playbackPosition,
playbackDuration,
rate,
} = this.state;
if (permissionError)
return (
<View
style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
}}
>
<Text>It looks like you haven't accepted the permission</Text>
</View>
);
return (
<AudioContext.Provider
value={{
audioFiles,
dataProvider,
playbackObj,
soundObj,
currentAudio,
isPlaying,
currentAudioIndex,
totalAudioCount: this.totalAudioCount,
playbackPosition,
playbackDuration,
rate,
updateState: this.updateState,
loadPreviousAudio: this.loadPreviousAudio,
onPlaybackStatusUpdate: this.onPlaybackStatusUpdate
}}
>
{this.props.children}
</AudioContext.Provider>
);
}
}
import {Component} from 'react';
import AsyncStorageLib from '#react-native-async-storage/async-storage';
export default AudioProvider;
and here's some more:
// play audio
// Import the react-native-sound module
import { PitchCorrectionQuality,shouldCorrectPitch, rate } from "expo-av/build/AV.types";
export const play = async (playbackObj, uri,) => {
try {
return await playbackObj.loadAsync(
{uri},
{shouldPlay: true},
);
} catch (error) {
console.log('error inside play helper method', error.message)
}
};
//pause
export const pause = async playbackObj => {
try {
// playbackObj.setRateAsync(rate = 2.0, shouldCorrectPitch = true, PitchCorrectionQuality= High);
return await playbackObj.setStatusAsync({
shouldPlay: false},
);
} catch (error) {
console.log('error inside pause helper method', error.message)
}
};
//resume
export const resume = async playbackObj => {
try {
return await playbackObj.playAsync(
);
} catch (error) {
console.log('error inside pause resume method', error.message)
}
};
//select next
export const playNext = async (playbackObj, uri) => {
try {
await playbackObj.stopAsync()
await playbackObj.unloadAsync();
return await play(playbackObj, uri);
} catch (error) {
console.log('error inside playNext helper method')
}
}
I've tried including 'rate: 2.0' inside this.state{audioFiles: [],
permissionError: false, etc.} but it didn't work.
Also I've tried doing: await playbackObj.setRateAsync() in the 2nd code snippet.
Any suggestions?
Nvm, I found the solution. Here's my updated code:
// play audio
// Import the react-native-sound module
import { PitchCorrectionQuality,shouldCorrectPitch, rate } from "expo-av/build/AV.types";
export const play = async (playbackObj, uri,) => {
try {
await playbackObj.loadAsync(
{uri},
{shouldPlay: true},
);
return await playbackObj.setStatusAsync({ rate: 0.9749090909 });
} catch (error) {
console.log('error inside play helper method', error.message)
}
};
//pause
export const pause = async playbackObj => {
try {
return await playbackObj.setStatusAsync({
shouldPlay: false,
rate: 0.9749090909,
});
} catch (error) {
console.log('error inside pause helper method', error.message)
}
};
//resume
export const resume = async playbackObj => {
try {
return await playbackObj.playAsync(
);
} catch (error) {
console.log('error inside pause resume method', error.message)
}
};
//select next
export const playNext = async (playbackObj, uri) => {
try {
await playbackObj.stopAsync()
await playbackObj.unloadAsync();
return await play(playbackObj, uri);
} catch (error) {
console.log('error inside playNext helper method')
}
}
It should call only once. When NetInfo.addEventListener calls it call three times. I want to call it once.
NetInfo.fetch().then(state => {
props.connectionState(state.isConnected)
NetInfo.addEventListener('connectionChange', state => {
props.connectionState(state.isConnected)
AsyncStorage.getItem('responseData').then(data => {
if (data !== null) {
let response = JSON.parse(data)
console.log('length', response.length)
response.forEach(element => {
props.submitDataOffline(element)
});
}
});
});
});
You need to unsubscribe each of your subscribed listeners. Otherwise they will accumulate as you load the view.
// component methods to register networkInfo
componentDidMount() {
this.unsubscribe = NetInfo.addEventListener(this.connectionChange);
}
// component methods to unregister networkInfo and appState listener
componentWillUnmount() {
this.unsubscribe();
}
So I would rewrite your code as follows:
constructor(props) {
NetInfo.fetch().then(state => props.connectionState(state.isConnected)});
this.unsubscribe = NetInfo.addEventListener('connectionChange', state => {
props.connectionState(state.isConnected)
AsyncStorage.getItem('responseData').then(data => {
if (data !== null) {
let response = JSON.parse(data)
console.log('length', response.length)
response.forEach(element => {
props.submitDataOffline(element)
});
}
});
});
});
}
componentWillUnmount() {
this.unsubscribe();
}
here is my solution
useEffect(() => {
let unsubscribe
let currentState
// Subscribe NetInfo event
unsubscribe = NetInfo.addEventListener(state => {
if (currentState !== state.isConnected) {
currentState = state.isConnected
console.log("Is connected?", currentState);
}
});
return () => {
console.log("unsubscribe");
if (unsubscribe)
unsubscribe();
};
}, []);
I have two components, in first components storing data in asyncstorage, in second component display data, when install app and save data does not get data from asyncstorage, when open app second time data are displayed.
storeData = async (item, messave, messrem) => {
const checkarary = this.state.favorite;
if(checkarary.some(e => e.name === item.name)) {
const value = this.state.favorite;
const position = value.filter((lists) => lists.id !== item.id);
this.setState({
favorite: position
}, () => {
try {
AsyncStorage.setItem('favoriti', JSON.stringify(this.state.favorite), () => {
Toast.show({
text: messrem,
buttonText: "Okay",
duration: 3000,
type: "danger"
});
});
} catch (error) {
}
});
} else {
this.setState({
favorite: [...this.state.favorite, item]
}, () => {
try {
AsyncStorage.setItem('favoriti', JSON.stringify(this.state.favorite), () => {
// AsyncStorage.getItem('favoriti', (err, result) => {
// console.log(result);
// });
Toast.show({
text: messave,
buttonText: "Okay",
duration: 3000,
type: "success"
});
});
} catch (error) {
}
});
}
};
Getting data in second component
_retrieveData = async () => {
try {
AsyncStorage.getItem('favoriti').then((value) => {
const parsed = JSON.parse(value);
this.setState({ favorite: parsed })
})
} catch (error) {
}
};
componentDidMount() {
this._retrieveData();
setTimeout(() => {
this.setState({
loading: false,
})
}, 2000)
};
componentDidUpdate() {
this._retrieveData();
};
How fix this issue, is there some solution. Can I set Item and reload app when install app or somthing else.
Use this
componentWillMount() {
this._retrieveData();
setTimeout(() => {
this.setState({
loading: false,
})
}, 2000)
};
instead of
componentDidMount() {
this._retrieveData();
setTimeout(() => {
this.setState({
loading: false,
})
}, 2000)
};
As componentWillMount is called after constructor is called for class and componentDidMount is called after screen is once rendered.
I am using React Native with Expo, and I am able to create users + rooms and send messages to them with the following code:
const hooks = {
onMessage: message => {
console.log("message", message);
this.setState({
messages: [...this.state.messages, message]
});
},
onUserStartedTyping: user => {
this.setState({
usersWhoAreTyping: [...this.state.usersWhoAreTyping, user.name]
});
},
onUserStoppedTyping: user => {
this.setState({
usersWhoAreTyping: this.state.usersWhoAreTyping.filter(
username => username !== user.name
)
});
},
onPresenceChange: () => this.forceUpdate()
};
class SetupChatKit extends React.Component {
constructor(props) {
super(props);
this.state = {
chatManager: null,
currentUser: {},
currentRoom: {},
messages: [],
usersWhoAreTyping: []
};
}
componentDidMount() {
const { userId, name } = this.props;
this.instantiateChatManager(userId);
this.createChatKitUser({ userId, name });
}
joinOrCreateChatKitRoom = (mode, chatKitRoomId, title) => {
const { chatManager } = this.state;
return chatManager
.connect()
.then(currentUser => {
this.setState({ currentUser });
if (mode === "join") {
return currentUser.joinRoom({ roomId: chatKitRoomId, hooks });
}
return currentUser.createRoom({
name: title,
private: false,
hooks
});
})
.then(currentRoom => {
this.setState({ currentRoom });
return currentRoom.id;
})
.catch(error => console.error("error", error));
};
instantiateChatManager = userId => {
const chatManager = new Chatkit.ChatManager({
instanceLocator: "v1:us1:9c8d8a28-7103-40cf-bbe4-727eb1a2b598",
userId,
tokenProvider: new Chatkit.TokenProvider({
url: `http://${baseUrl}:3000/api/authenticate`
})
});
this.setState({ chatManager });
};
My problem is that console.log("message", message); never gets called, even when I manually add messages to the room via the online control panel.
I've tried logging from chatManager, and that looks like the following:
As you can see from the documentation, the onMessage hook needs to be attached on subscribeRoom, not when joining a room.
https://docs.pusher.com/chatkit/reference/javascript#connection-hooks
So probably add subscribeToRoom() after the first success promise in your joinOrCreateChatKitRoom() method.
I refactored the code with async/await and used .subscribetoRoom() like so:
joinOrCreateChatKitRoom = async (mode, chatKitRoomId, title) => {
const { chatManager } = this.state;
try {
const currentUser = await chatManager.connect();
this.setState({ currentUser });
let currentRoom;
if (mode === "join") {
currentRoom = await currentUser.joinRoom({
roomId: chatKitRoomId
});
} else {
currentRoom = await currentUser.createRoom({
name: title,
private: false
});
}
this.setState({ currentRoom });
await currentUser.subscribeToRoom({
roomId: currentRoom.id,
hooks: {
onMessage: message => {
this.setState({
messages: [...this.state.messages, message]
});
},
onUserStartedTyping: user => {
this.setState({
usersWhoAreTyping: [...this.state.usersWhoAreTyping, user.name]
});
},
onUserStoppedTyping: user => {
this.setState({
usersWhoAreTyping: this.state.usersWhoAreTyping.filter(
username => username !== user.name
)
});
},
onPresenceChange: () => this.forceUpdate()
}
});
return currentRoom.id;
} catch (error) {
console.error("error creating chatManager", error);
}
};