undefined is not an object (evaluating '_effects.buffers.expanding') - react-native

I'm getting an error when tried to copy&paste this solution in my app.
undefined is not an object (evaluating 'effects.buffers.expanding')
My code is pretty similar:
export function* handleBleState() {
const {
bleConnections: { manager },
} = yield select()
const stateChannel = yield eventChannel((emit) => {
const subscription = manager.onStateChange((state) => {
emit(state)
}, true)
return () => {
subscription.remove()
}
}, buffers.expanding(1))
try {
for (;;) {
const newState = yield take(stateChannel)
const power = newState === 'PoweredOn'
yield put(BLEActions.updateBleState(power))
}
} finally {
if (yield cancelled()) {
stateChannel.close()
}
}
}
But what is more strange is that I have extracted code from the documentation of redux-saga and the error is similar.
I replaced part of the code with this:
const stateChannel = yield eventChannel((emitter) => {
const iv = setInterval(() => {
secs -= 1
if (secs > 0) {
emitter(secs)
} else {
// this causes the channel to close
emitter(END)
}
}, 1000)
// The subscriber must return an unsubscribe function
return () => {
clearInterval(iv)
}
})
And I get:
undefined is not a function (evaluating '(0, _effects.eventChannel)')
I'm using another version of redux-saga:
"redux-saga": "^1.0.2",
But I tried with the same version that he use
"redux-saga": "0.16.2"
And then the issue is another one:
console.error: "unchaught at root", "at root at takeLatest" at handleBleState etc, etc.
Any help will be welcome, thanks in advance.
PD:
"react": "16.6.1",
"react-native": "0.57.5",
"react-native-ble-plx": "^1.0.1",

the eventChannel is nor part of the effects but defined directly in the main module, see the relevant API doc. So if you're using ES6 import/export you import it with the following statement:
import { eventChannel } from 'redux-saga'
While the require equivalent should be:
const eventChannel = require('redux-saga').eventChannel

Related

Mobx how to compute values in state

I'm new to Mobx and I can't work out how to compute a value in my store.
I'm following the docs description of using the 'computed' modifier.
Here's my (cut down) appState:
export default class AppState {
constructor() {
/* MOBX STATE */
extendObservable(this, {
// Links
'links': [],
'updateLinks': action((newlinks) => {
this.links = newlinks;
}),
'linksWithComments': computed(() => this.links),
});
}
}
'links' works fine in my React components, but when I add 'linksWithComments' I see this error:
Uncaught Error: [MobX] 'keys()' can only be used on observable objects, arrays, sets and maps
What am I doing wrong? 'links' is an array, and as far as I can tell it's observable, so what does the error mean? I've googled for the error message but haven't found anything that explains what's going on.
I've tried this form also:
get linksWithComments () { return 2*3; },
In this case 'linksWithComments' is undefined.
Versions:
"mobx": "^6.1.8",
"mobx-react": "^7.1.0",
"mobx-react-lite": "^3.2.0",
Thank you!
Preferred way to use MobX#6 with classes is to use makeAutoObservable or makeObservable:
class AppState {
links = [];
constructor() {
makeAutoObservable(this);
}
updateLinks = (newLinks) => {
this.links = newLinks;
};
get linksWithComments() {
return this.links.filter((link) => link > 0.5);
}
}
Have you tried it?
I've made Codesanbox example for you to explore!
More info in the official docs

TypeError: _rxjs.Observable.fromPromise is not a function

I use rxjs in React Native. I call Observable.fromPromise(storage.load({key: key})).map(() => value); shows the error.
My rxjs version:
"rxjs": "^6.5.3",
"rxjs-compat": "^6.5.3",
I have three steps.
Step1:
rxInit().flatMap(() => {
console.log('I can not see the console log');
return rxInit()
}).subscribe(() => {
console.log('I can not see the console log');
// some code...
})
Step2 rxInit():
import { Observable } from 'rxjs';
rxInit() {
console.log('I can see the console log')
return StorageService.shared.get('deviceuuid').flatMap((deviceuuid) => {
console.log('I can't not see the console log')
if (deviceuuid == null) {
return StorageService.shared.set('deviceuuid', this.deviceuuid);
} else {
return Observable.of(this.deviceuuid);
}
}).do((deviceuuid) => {
// some code...
})
}
Step3 about the get():
import { Observable } from 'rxjs';
import Storage from 'react-native-storage';
import AsyncStorage from '#react-native-community/async-storage';
let storage = new Storage({
size: 1000,
storageBackend: AsyncStorage,
defaultExpires: null,
})
export default class StorageService {
set(key, value) {
console.log('StorageService set');
return Observable.fromPromise(storage.save({ key: key, data: value })).map(() => value);
}
get(key) {
console.log('It is a ', storage.load({key: key})); // It is a Promise
return Observable.fromPromise(storage.load({key: key})).map(() => value);
}
remove(key) {
return Observable.fromPromise(storage.remove({key: key})).catch(() => Observable.of(null))
}
}
StorageService.shared = new StorageService();
I looking for some answer, somebody says it is because rxjs is above 6.0, so I try to use
import { from } from 'rxjs';
return from(storage.load({key: key})).map(() => value);
It sill shows
TypeError: _rxjs.from.fromPromise is not a function
or
_rxjs.from().map is not a function.
Any help would be appreciated.
I understand that there are already some hints on the comments, but I will provide an answer to give more context to the answer.
For RxJS 6, the practice when it comes to working with RxJS operators (such as map and switchMap) would be to use the pipe utility, rather than dot-chaining the operators. You may read more about the changes over here.
Building onto your example, for instance, if you want to use both map and filter operators, rather than doing something like
from(storage.load({key: key})).map(() => value).filter(value => value)
RxJS 6 will require you to do this instead:
from(storage.load({key: key}))
.pipe(
map(() => value),
filter(value => value),
.subscribe(res => {
console.log(res);
// do the rest here
})

relay subscription onNext not triggered on react-native

I am a subscription setup but onNext is not getting triggered I am not sure why since this is my first time implementing subscription and docs was not much help with the issue.
Here are the code implementations:
import {
graphql,
requestSubscription
} from 'react-relay'
import environment from '../network';
const subscription = graphql`
subscription chatCreatedSubscription{
chatCreated{
id
initiate_time
update_time
support_id
category_id
email
name
}
}
`;
function chatCreated(callback) {
const variables = {};
requestSubscription(environment, {
subscription,
variables,
onNext: () => {
console.log("onNext");
callback()
},
updater: () => {
console.log("updater");
}
});
}
module.exports = chatCreated;
and here is my network for the subscription
import { Environment, Network, RecordSource, Store } from "relay-runtime";
import Expo from "expo";
import { SubscriptionClient } from "subscriptions-transport-ws";
import { WebSocketLink } from 'apollo-link-ws';
import { execute } from 'apollo-link';
import accessHelper from "../helper/accessToken";
const networkSubscriptions = async (operation, variables) => {
let token = await accessHelper();
if (token != null || token != undefined) {
const subscriptionClient = new SubscriptionClient("ws://localhost:3000/graphql",
{
reconnect: true,
connectionParams: {
Authorization: token,
},
});
execute(new WebSocketLink(subscriptionClient), {
query: operation.text,
variables,
});
}
}
const network = Network.create(fetchQuery, networkSubscriptions);
const store = new Store(new RecordSource());
const environment = new Environment({
network,
store
});
export default environment;
the subscription is called in a componentDidMount method on a component it executes but the onNext method inside the subscription is never triggered when new information is added to what the subscription is listening to.
so i figured out that my issue was the network js not being setup properly and the version of subscription-transport-ws. i added version 0.8.3 of the package and made the following changes to my network file:
const networkSubscriptions = async (config, variables, cacheConfig, observer) => {
const query = config.text;
let token = await accessHelper();
if (token != null || token != undefined) {
const subscriptionClient = new SubscriptionClient(`ws://${api}/graphql`,
{
reconnect: true,
connectionParams: {
Authorization: token,
},
});
subscriptionClient.subscribe({ query, variables }, (error, result) => {
observer.onNext({ data: result })
})
return {
dispose: subscriptionClient.unsubscribe
};
}
}
i hope this helps you if you get stuck with the same issue as mine.

"Maximum call stack size exceeded" by passing the data to the Vuex-state

I am fetching the data from a MongoDB through sending GET requests to my API. Then I loop through the response.data and in each response.data through its properties to push the data which I need to nextArray. And this nextArray should be passed to the schedulingQuality-state in the Vuex. That's how it looks like:
methods: {
...mapActions(
['setSchedulingQuality']
),
get_data() {
const nextArray = [];
for(let i in this.SelectedtValues) {
axios.get('http://127.0.0.1:5000/getexp/'+this.SelectedtValues[i])
.then(res => {
for(let n in res.data) {
nextArray.push(res.data[n].output)
}
}
)}
console.log(nextArray);
},
computed: {
...mapGetters(
['schedulingQuality','selectedValues']
),
SelectedtValues() {
return this.$store.getters.selectedValues;
} ,
schedulingQuality() {
return this.schedulingQuality;
}
}
When I'm printing out the nextArray then it seems to be ok. I'm getting a [] on the console and after I click on it the correct content appears with a small i icon which tells: "Value below was evaluated just now". However I am not able to print out the items of this Array separately, each of them has a value of undefined, when I try that.
But my main problem is that it throws an Maximum call stack size exceeded error, when I'm trying to pass it to my Vuex-state in the code above befor printing out, like:
this.setSchedulingQuality(nextArray)
Here is my Vuex-code:
import Vuex from "vuex";
import axios from "axios";
const createStore = () => {
return new Vuex.Store({
state: {
schedulingQuality: [],
},
mutations: {
SchedulingQuality(state, payload) {
state.schedulingQuality = payload;
}
},
actions: {
setSchedulingQuality({commit}, payload){
commit('SchedulingQuality',payload)
}
},
getters: {
schedulingQuality(state) {
return state.schedulingQuality;
}
}
});
};
export default createStore;
My questions are:
Why it is not possible to print out the Array items separately?
Why I'am getting this error
And how can I fix it?
Thank you for your time.
axios call is asynchronous. At the time you call console.log(nextArray), axios function is not finished yet. That's why you got empty array.
You call multiple api asynchronously, I suggest you check out Promise.all
get_data() {
const nextArray = [];
Promise.all(this.SelectedtValues.map(value => {
return axios.get('http://127.0.0.1:5000/getexp/' + value)
})).then(results => {
results.map(res => {
for(let n in res.data) {
nextArray.push(res.data[n].output)
}
})
console.log(nextArray);
}).catch(err => {
console.error(err)
})
}

Unable to get async/await working in react native

I have not been able to get async/await working in a react native project.
const async getUser = () => {
try{
let value = await AsyncStorage.getItem("user");
return value;
}
catch(e){
throw e
}
}
I always get an Unexpected token error. I have tried adding { "presets": ["react-native", "es2015", "babel-preset-stage-3"] } with the same result.
On version ^0.35.0
The syntax for async arrow functions is:
const getUser = async () => {
...
}