Filter api React if === result - api

Hello i'm fetching an Star Wars api and i'm trying to filter characters by affiliations, exemple fetch all who are affiliate to the New Republic.
Array(87)
0:
affiliations: Array(10)
0: "Alliance to Restore the Republic"
1: "Red Squadron"
2: "Rogue Squadron"
3: "Massassi Group"
4: "Leia Organa's team"
5: "Endor strike team"
6: "Jedi Order"
7: "Bright Tree tribe"
8: "New Republic"
9: "Resistance"
length: 10
Here my useEffect:
axios
.get(`https://cdn.rawgit.com/akabab/starwars-api/0.2.1/api/all.json`)
.then((res) => {
setData(res.data);
console.log(res.data);
console.log("filter",res.data[1].affiliations[1]);
setLoading(false);
})
.catch((err) => {
console.log(err);
});
}, []);
here is my map:
{data.map((all, i) => (
<Card key={i} {...all} />
))}
i know ho to do with a search input like this:
data &&
data.filter((val) => {
if (data === "New Republic") return val;
return val.name.toLowerCase().includes(search.toLowerCase());
});
but i don't know how to do with an include method maybe ?

Related

Cypress How can I get length of API response data? Please see github link and image link

here is code and https://github.com/chkashif167/Partie.Tests/blob/master/cypress/integration/1profile/get-parties.counts.profile.spec.js and here is result of code https://www.screencast.com/t/ngRKLRYsc but I want compare 46 length with count of parties in UI `
describe("Partie Counts Profile Page Test", () => {
before(function() {
cy.SignIn();
cy.fixture("vars.json").as("vars");
});
it("Partie Counts", () => {
const profileBtn = "div.actions--left > button > img";
///// I want to get lenght of the parties from the url response and want check with counts in UI
cy.wait(3000);
cy.get(profileBtn).click();
cy.wait(1000);
cy.request(
"api/v1/room/getUserRooms/d23eef09-e4e1-455d-a74c-03dfc61bde11"
).then(response => {
cy.log(response.body);
assert.equal(response.status, 200);
expect(response.body).to.not.be.null;
cy.log(response.body.length);
cy.get("div:nth-child(3) > span.quick-stat-figure").should("contain",response.body.length);
});
});
});
Finally Successfully checked the length
describe("Partie Counts Profile Page Test", () => {
before(function() {
cy.SignIn();
cy.fixture("vars.json").as("vars");
});
it("Partie Counts", () => {
const profileBtn = "div.actions--left > button > img";
///// I want to get lenght of the parties from the url response and want check with counts in UI
cy.wait(3000);
cy.get(profileBtn).click();
cy.wait(1000);
cy.server();
cy.route({
method: "GET",
url: "api/v1/room/getUserRooms/d23eef09-e4e1-455d-a74c-03dfc61bde11"
}).as("get_jobs");
cy.wait("#get_jobs").then(xhr => {
cy.log(xhr.response.body.length);
cy.get("div:nth-child(3) > span.quick-stat-figure").should(
"contain",
xhr.response.body.length
);
});
});
});

React Native: Phone number not updating and continuing to give error message

I have a bug in my application where I am trying to update a phone number and when I click on save, I get the error message and the original phone number stays populated:
Obviously, something has gone wrong with validation. I was hoping it was perhaps the regex although it has a solid one, but I changed it like so:
const regex = {
userName: /^[-.\sa-zA-Z]+$/,
cardName: /^[-\sa-zA-Z]+$/,
password: /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&*()\-+!\\.]?).{8,}$/,
zip: /(^\d{5}$)|(^\d{5}-\d{4}$)/,
memberId: /^\d+$/,
// phoneNumber: /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/,
phoneNumber: /^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im,
email: /^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/,
};
That did not help.
I am thinking it has to be the validation function, but I am staring at this thing and I can't see anything that sticks out:
_validate = props => {
const validationErrors = {
businessName: props.businessName ? '' : 'Is Required',
businessPhoneNumber:
props.businessPhoneNumber.length === 0 ||
regex.phoneNumber.test(props.businessPhoneNumber)
? ''
: 'Phone number must be valid and contain 10 digits',
};
const isValid = Object.keys(validationErrors).reduce((acc, curr) => {
if (validationErrors[curr] !== '') {
return false;
}
return acc;
}, true);
this.setState({validationErrors, displayErrors: !isValid});
return isValid;
};
UPDATE
I tried the solution in the below answer, but unfortunately that did not work.
Here is whats going on:
When I add the phone number and save it, it is in props here:
_validate = props => { and you can see that here:
{screenProps: undefined, navigation: {…}, businessName: "Ceramic Tile Distributors", businessWebsite: "", businessPhoneNumber: "8667073945", …}
but then it ceases to exist in the validationErrors object here:
const validationErrors = {
businessName: props.businessName ? "" : "Is Required",
businessPhoneNumber:
props.businessPhoneNumber.length === 0 ||
regex.phoneNumber.test(props.businessPhoneNumber)
? ""
: "Phone number must be valid and contain 10 digits"
};
and you can see that here:
{businessName: "", businessPhoneNumber: ""}
Why its re-rendering with the above as empty strings I do not know.
I can tell you that this here:
const isValid = Object.keys(validationErrors).reduce((acc, curr) => {
console.log("On line 84 of BusinessDetails: ", isValid);
if (validationErrors[acc] !== "") {
return false;
}
return acc;
}, true);
returns undefined, but why I do not know.
_validate is being used inside the _saveChanges function like so:
_saveChanges = () => {
const isValid = this._validate(this.props);
if (isValid) {
this.setState({ displaySpinner: true });
this.props
.updateInformation()
.then(() => {
this.setState({ displaySpinner: false }, () => {
this.props.navigation.goBack();
});
})
.catch(() => {
Alert.alert(
"Error",
this.props.businessPhoneNumber.length === 0
? "Please provide a business phone number. If your business phone number no longer exists, please call 1-800-NFIB-NOW to have this information deleted."
: "We couldn't save your changes. Please try again.",
[
{
text: "OK",
onPress: () => this.setState({ displaySpinner: false })
}
],
{ cancelable: false }
);
});
}
};
I can tell you that const isValid = this._validate(this.props); returns false.
When I test your code, it looks like there is no problem with your regex. But the below line is not correct
if (validationErrors[curr] !== '') {
return false;
}
You should use acc to get the values. consider the below code
if (validationErrors[acc] !== '') {
return false;
}
However, I can't run your code in my system. .reduce not working here. As a workaround, you can use below code
_validate = props => {
const validationErrors = {
businessName: props.businessName ? '' : 'Is Required',
businessPhoneNumber:
props.businessPhoneNumber.length === 0 ||
regex.phoneNumber.test(props.businessPhoneNumber)
? ''
: 'Phone number must be valid and contain 10 digits',
};
let isValid = true
Object.keys(validationErrors).map((acc, curr) => {
if (validationErrors[acc] !== '') {
isValid= false
}
});
this.setState({validationErrors, displayErrors: !isValid});
return isValid;
};

How to transform correctly data.map to Object.keys?

I had an array of data. 7 items for which I used data.map. I loaded this array on firebase and now I can't call it like this . Because this is not the Array is already in the Objects.
Question.
How do I do data.map for Objects. Moreover, I need to transfer data. Specifically: id, name , info , latlng. Inside is the ImageCard that should be in the data.map.
Example object:
Object {
"0": Object {
"id": 0,
"image": "/images/Stargate.jpg",
"info": "Stargate is a 1994 science fiction adventure film released through Metro-Goldwyn-Mayer (MGM) and Carolco Pictures..",
"latlng": Object {
"latitude": 53.6937,
"longitude": -336.1968,
},
"name": "Stargate",
"year": "1994",
},
I was advised to use Object.keys but still works incorrectly.
Since it was originally:
const url =""
then:
try {
const response = await fetch(url);
const data = await response.json();
this.setState({ data });
} catch (e) {
throw e;
}
in the render(){:
const { title, data , label } = this.state;
in the return:
{data.map(item => (
<ImageCard
data={item}
key={item.id}
onPress={() =>
navigation.navigate(IMAGEPROFILE, {
show: item,
onGoBack: this.onGoBack
})
}
/>
))}
in the ImageCard:
const ImageCard = ({ data, onPress }) => {
const { image, name, year } = data;
For the Object.keys I take data like this:
firebase
.database()
.ref("/events/" )
.once("value", data => {
if(data !== null){
this.setState({
data })
console.log(data.toJSON())
}
})
How to correct my example to transform data.map to Object.keys ?
use Object.keys and map on the returned array.
The Object.keys() method returns an array of a given object's own property names, in the same order as we get with a normal loop.
{
Object.keys(data).map(item => ( <
ImageCard data = { item } key = { item.id } onPress = {
() =>
navigation.navigate(IMAGEPROFILE, {
show: item,
onGoBack: this.onGoBack
})
}
/>
))
}

Is there a way to do pagination with firebase realtime database (vuejs)?

I'm trying to paginate my data from firebase realtime database.
Do I have to change to firestore ? Where all is explain in Google's doc (https://firebase.google.com/docs/firestore/query-data/query-cursors) or it's also possible with rtdb ?
Here is my code (i'm using vue js) :
loadConcerts ({commit}) {
commit('setLoading', true)
firebase.database().ref('concerts')
.orderByChild('expires')
.startAt(Date.now() / 1e3)
.limitToFirst(10)
.once('value')
.then(data => {
const concerts = []
data.forEach(element => {
concerts.push({
id: element.key,
title: element.val().title,
day: element.val().day,
ticketlink: element.val().ticketlink,
description: element.val().descriptio
})
})
commit('setLoadedConcerts', concerts)
commit('setLoading', false)
})
.catch(
(error) => {
console.log(error)
commit('setLoading', false)
}
)
},
I would like to add pagination after 10 results, or infinite scrolling.
I have also had similar problem with pagination. The documentation seems to be insufficient i.e they show you how to go to next page but not how to move back to the previous page. Its just frustrating really.
I am using firestore
Below is how i implemented a simple pagination. I have already configured VueFire , Firebase and BootstrapVue i'll head straight to the code.
What to do different that no one shows you.
Use VueFire programmatic binding instead of declarative binding see here
To get firstVisible item in firebase run documentSnapshots.docs[0]
<template>
<div>
<p>{{countries}}</p>
<b-button-group size="lg" class="mx-2">
<b-button :disabled="prev_btn" #click="previous" >«</b-button>
<b-button :disabled="next_btn" #click="next">»</b-button>
</b-button-group>
</div>
</template>
<script>
import firebase from 'firebase/app'
import 'firebase/auth'
import { db } from '../main'
export default {
name: 'Countries',
data () {
return {
countries: [],
limit: 2,
lastVisible: '',
firstVisible: '',
next_btn: false,
prev_btn: true
}
},
methods: {
next () {
if (!this.next_btn) {
// bind data with countries
this.$bind('countries', db.collection('Countries').orderBy('createdAt').startAfter(this.lastVisible).limit(this.limit))
// set last and first visible items
db.collection('Countries').orderBy('createdAt').startAfter(this.lastVisible).limit(this.limit).get().then(documentSnapshots => {
this.lastVisible = documentSnapshots.docs[documentSnapshots.docs.length - 1]
this.firstVisible = documentSnapshots.docs[0]
}).then(() => {
// Peep on the next next query to see if it gives zero
db.collection('Countries').orderBy('createdAt').startAfter(this.lastVisible).limit(this.limit).get()
.then(snap => {
if (snap.size === 0) {
//disable button if the next peeped result gets zero
this.next_btn = true
// enable previous button
this.prev_btn = false
} else {
// enable next button if peeped result is not zero
this.next_btn = false
// enable previous button
this.prev_btn = false
}
})
})
}
},
previous () {
// Ensure previous is not zero
db.collection('Countries').orderBy('createdAt').endBefore(this.firstVisible).limitToLast(this.limit).get().then(snap => { return snap.size })
.then(size => {
//confirm is not zero here
if (size !== 0) {
//bind the previous to countries
this.$bind('countries', db.collection('Countries').orderBy('createdAt').endBefore(this.firstVisible).limitToLast(this.limit))
// Set last and first visible
db.collection('Countries').orderBy('createdAt').endBefore(this.firstVisible).limitToLast(this.limit).get().then(documentSnapshots => {
this.lastVisible = documentSnapshots.docs[documentSnapshots.docs.length - 1]
this.firstVisible = documentSnapshots.docs[0]
}).then(() => {
// peep the next previous query
db.collection('Countries').orderBy('createdAt').endBefore(this.firstVisible).limitToLast(this.limit).get()
.then(snap => {
if (snap.size === 0) {
//if next peeped previous button gets 0 disable
this.prev_btn = true
this.next_btn = false
} else {
//if next peeped result is does not get 0 enable buttons
this.prev_btn = false
this.next_btn = false
}
})
})
}
})
}
},
mounted () {
// run first query and bind data
this.$bind('countries', db.collection('Countries').orderBy('createdAt').limit(this.limit))
// set last and first Visible
db.collection('Countries').orderBy('createdAt').limit(this.limit).get().then(documentSnapshots => {
this.lastVisible = documentSnapshots.docs[documentSnapshots.docs.length - 1]
this.firstVisible = documentSnapshots.docs[0]
}).then(() => {
// peep to check if next should be on or off
db.collection('Countries').orderBy('createdAt').startAfter(this.lastVisible).limit(this.limit).get()
.then(snap => {
if (snap.size === 0) {
this.next_btn = true
}
})
})
}
}
</script>

React native picker, get selected option text

I am using my react native picker with options like so:
<Picker
selectedValue={student}
label="Student"
style={styles.picker}
onChange={this.onStudentChange}
options={
categories
.find(category => {
return category.id == year;
})
.options.find(category => {
return category.id == group;
})
.options
}
/>
I then dispatch and action in my click handler, where e is the id of the student:
onStudentChange(e) {
if (e !== "") {
this.props.setStudent(e);
}
}
How can I get the selected option text as well as the value?
You can find the selected option by id from the list of options. After that you can get a text from the selected option. In the example below I moved the code that gets the options into a separate function which I also use in onStudentChange:
getOptions(year, group) {
return categories
.find(category => {
return category.id == year;
})
.options.find(category => {
return category.id == group;
})
.options
}
onStudentChange(e) {
if (e !== "") {
// Find option by id and get text.
const text = this.getOptions().find(entry => entry.id === e).text;
this.props.setStudent(e);
}
}
render() {
...
<Picker
selectedValue={student}
label="Student"
style={styles.picker}
onChange={this.onStudentChange}
options={this.getOptions(year, group)}
/>
}