graphene django relay: Relay transform error - python

Being very new to GraphQL, I have a graphene django implementation of a server with two models, following rather closely the graphene docs' example.
In graphiql, I can do this, and get a result back.
Following another relay tutorial, I'm intending to render the result of this query on screen.
My attempt looks like this:
class Note extends Component {
render() {
return(
<div> {this.props.store.title} </div>
)
}
}
Note = Relay.createContainer(Note, {
fragments: {
store: () => Relay.QL`
fragment on Query {
note(id: "Tm90ZU5vZGU6MQ==") {
id
title
}
}
`
}
});
class NoteRoute extends Relay.Route {
static routeName = 'NoteRoute';
static queries = {
store: Component => {
return Relay.QL`
query {
${Component.getFragment('store')}
}
`},
};
}
My browser's console shows the following error:
Uncaught Error: Relay transform error ``There are 0 fields supplied to the query named `Index`, but queries must have exactly one field.`` in file `/Users/.../src/index.js`. Try updating your GraphQL schema if an argument/field/type was recently added.
I've been trying to figure it out on my own with limited success.
Can someone point me in the right direction?

Thanks #stubailo for pointing me in the right direction. I made some adjustments, and now have a minimum example running like this:
NoteList = Relay.createContainer(NoteList, {
fragments: {
store: () => Relay.QL`
fragment N on NoteNodeConnection {
edges {
node{
id
title
note
}
}
}
`
}
});
class NoteRoute extends Relay.Route {
static routeName = 'NoteRoute';
static queries = {
store: Component => {
return Relay.QL`
query {
notes {
${Component.getFragment('store')}
}
}
`},
};
}

Related

The code is forcing the user to change the image also when he want to change only other properties of his article

Hello everyone I have a blog platform, the user can add and edit blog. I used Django and Django Rest Framework to build the website, and for the frontend ReactJS. My problem is when I edit blog I couldn't save the changes until I change the image.
in React edit.js
const handleSubmit = (e) => {
e.preventDefault();
console.log(formData);
let ss = new FormData();
ss.append('title', formData.title);
ss.append('slug', formData.slug);
ss.append('content', formData.content);
ss.append('image', postimage.image[0]);
axiosInstance.patch(`admin/edit/`+ id + '/', ss, {
headers:{
Authorization: `JWT ${localStorage.getItem('refresh_token')}`
},
},)
};
Any hint or guidance will be really helpful for me to complete the project because I have been stuck in it for more than two weeks.
The problem is with handleSubmit, you cannot read the value of postimage if it is null:
const handleSubmit = (e) => {
e.preventDefault();
console.log(formData);
let ss = new FormData();
ss.append('title', formData.title);
ss.append('slug', formData.slug);
ss.append('content', formData.content);
if (postimage != null) {
ss.append('image', postimage.image[0]);
}
axiosInstance.patch(`admin/edit/`+ id + '/', ss, {
headers:{
Authorization: `JWT ${localStorage.getItem('refresh_token')}`
},
},)
.then((res) => {
// navigate('/admin/');
});
};
Remember to set required=False for the image field of BlogSerializer.

How to check if a Firestore collection exists without knowing document name/ID with Python [duplicate]

Is there a way to check if a sub collection exists in firestore for nodejs?
Currently I am using doc.exists for documents but I need to check if a subcolletion exists within a document in order to write some data or not.
Yes, there is. You can use docs.length to know if the subcollection exists.
I made a sample to guide you, hope it helps.
this.db.collection('users').doc('uid')
.get().limit(1).then(
doc => {
if (doc.exists) {
this.db.collection('users').doc('uid').collection('friendsSubcollection').get().
then(sub => {
if (sub.docs.length > 0) {
console.log('subcollection exists');
}
});
}
});
Mateus' Answer didn't help me. Probably it has been changed over the time.
.collection(..).get() returns a QuerySnapshot which has the property size, so I just did:
admin.firestore
.collection('users')
.doc('uid')
.collection('sub-collection')
.limit(1)
.get()
.then(query => query.size);
To be more precise:
const querySnapshot = await admin.firestore().collection('users').doc('uid').collection('sub-collection').limit(1).get()
if (querySnapshot.empty) {console.log('sub-collection not existed')}
This is how I was able to check if a collection exists?
I target the document path first, then if it exists, It means the collection afterwards exists and I can access it.
> db.collection("collection_name").document("doc_name").get()
> .addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
> #Override
> public void onComplete(#NonNull Task<DocumentSnapshot> task) {
> if(task.isSuccessful()){
> DocumentSnapshot result = task.getResult();
> if(result.exists()){
> *//this means the document exist first, hence the
> //collection afterwards the doc_name will
> //exist...now I can access the collection*
> db.collection("collection_name").document("doc_name").collection("collection_name2").get()
> .addOnCompleteListener(task1 -> { if(task1.isSuccessful()){
> ...
> } }); } } });
isEmpty property of QuerySnapshot returns true if there are no documents in the QuerySnapshot.
Thus you can simply check if isEmpty is true or false.
const subcolRef = collection(db, "parentCollectionTitle", "parentDocId", "subcollectionTitle")
const subcolSnapshot = await getDocs(subcollectionRef)
if (!subcolSnapshot.empty) {
console.log("subcol does exists!");
} else {
console.log("subcol does NOT exist!");
}
(Firebase v9)
This is NextJS (React) code for checking if a sub-collection "history" exists or not in collection "users" > doc>user-Id,
if it exists then take data in history, else keep have-history == false.
you can then use {havehistory?<></>:<></>} for showing different info, as per data.
const [history, setHistory] = useState([])
const [havehistory, setHavehistory] = useState(false)
if(user){
onSnapshot(query(collection(db, "users", user.uid,"history")), (querySnapshot) => {
if(querySnapshot){
const historyBro = querySnapshot.docs.map((doc) => {
return { ...doc.data(), id: doc.id };
});
setHistory(historyBro)
setHavehistory(true)
}
})
}
make sure your imported the required modules. e.g.
import { useState } from "react";
import {db} from '../firebase'
import { collection,doc, query, onSnapshot} from "firebase/firestore";
import Link from "next/link";

Retrieve all products with nested prices from stripe?

I enjoy the simplicity of the stripe APIs but I'm not sure if it's possible to retrieve nested objects. I'd love to be able to retrieve all products and prices to display them publically on my website.
I can list all prices and products like this:
stripe.Price.list(limit=3)
stripe.Products.list(limit=3)
On the frontend, I then have to write some logic that associates the prices with the products, makes the distinctions for monthly and yearly prices etc. I'd love to have this nested. Is this possible?
I'm also not entirely sure if it is safe to expose the returned information publically (API key is obviously hidden). I'd love some more info on this.
Whenever an id is present in an object, the expand parameter can be called to also return that item.
This can be further explored in the Stripe docs for Expanding Responses: https://stripe.com/docs/expand
A solution in nodejs would be the following:
const productPriceData = await stripe.prices.list({
expand: ['data.product'], // 🎉 Give me the product data too!
})
I actually came across the same issue and documented how I got to this solution here: https://blog.focusotter.com/fetch-both-price-and-product-data-from-stripe-in-a-single-api-call
On the frontend, I then have to write some logic that associates the prices with the products, makes the distinctions for monthly and yearly prices etc. I'd love to have this nested. Is this possible?
The approach would be to first list the Products from the API, then iterate over them and retrieve all the Prices associated with a given Product:
List all Prices: https://stripe.com/docs/api/prices/list?lang=python
While specifying the Product ID: https://stripe.com/docs/api/prices/list?lang=python#list_prices-product
The Product object doesn't contain a list of its Prices, so there is really no way around making the two separate requests: https://stripe.com/docs/api/products/object
I'm also not entirely sure if it is safe to expose the returned information publically (API key is obviously hidden). I'd love some more info on this.
This is a good question, since generally speaking only objects retrievable with a publishable key are safe to directly consume client-side from the Stripe API. In those cases the API reference marks the properties on the object as "retrievable with a publishable key", for example:
Retrieve a PaymentIntent client-side: https://stripe.com/docs/js/payment_intents/retrieve_payment_intent
Properties retrievable: https://stripe.com/docs/api/payment_intents/object
But, as long as your server-side endpoint doesn't directly return the Product/Price objects retrieved using your secret key, and instead returns a filtered version with just the required properties you should be fine!
Do it the other way around; get all the prices, then get the corresponding product.
Create your Stripe instance first, and then request the data from your function
// index.ts
import { getStripeProduct, getStripeProducts } from './products'
import * as express from 'express'
import Stripe from 'stripe'
const router = express.Router()
const stripe = (apiKey:string) => {
return new Stripe(apiKey, {
apiVersion: "2020-08-27",
typescript: true
});
}
// GET a product
router.get('/product/:id', async (req: express.Request, res: express.Response) => {
console.log(`API call to GET /public/product/${req.params.id}`)
await getStripeProduct(stripe(STRIPE_SECRET_KEY)), req.params.id )
.then((product) => {
respond(res, {data: product})
})
.catch((error) => {
respond(res, {code: error.statusCode, message: error.message})
})
})
// GET a product list
router.get('/products', async (req: express.Request, res: express.Response) => {
console.log('API call to GET /public/products')
await getStripeProducts(stripe(STRIPE_SECRET_KEY))
.then((products) => {
respond(res, {data: products})
})
.catch((error) => {
console.error(error)
respond(res, {code: error.statusCode, message: error.message})
})
})
// products.ts
import { ProductModel } from '../../models'
import { Stripe } from 'stripe'
export async function getStripeProduct(stripe: Stripe, id: string) {
return new Promise((resolve, reject) => {
stripe.prices.retrieve(id)
.then(async (price) => {
const product: ProductModel = {
id: price.id,
name: 'Unnamed Product',
price: price.unit_amount,
recurring: price.recurring || undefined,
metadata: price.metadata
}
if(typeof(price.product) == 'string') {
await stripe.products.retrieve(price.product)
.then((stripeProduct) => {
product.name = stripeProduct.name
product.caption = stripeProduct.description || undefined
product.images = stripeProduct.images || undefined
product.active = stripeProduct.active
resolve(product)
})
}
resolve(product)
})
.catch((error:any) => {
reject(error)
})
})
}
export async function getStripeProducts(stripe: Stripe) {
return new Promise((resolve, reject) => {
stripe.prices.list()
.then(async (prices) => {
const products: ProductModel[] = []
for(let price of prices.data) {
const product: ProductModel = {
id: price.id,
name: 'Unnamed Product',
price: price.unit_amount,
recurring: price.recurring || undefined,
metadata: price.metadata
}
if(typeof price.product == 'string') {
await stripe.products.retrieve(price.product)
.then((stripeProduct) => {
product.name = stripeProduct.name
product.caption = stripeProduct.description || undefined
product.images = stripeProduct.images || undefined
product.active = stripeProduct.active
products.push(product)
})
}
}
resolve(products)
})
.catch((error:any) => {
reject(error)
})
})
}
// Product Model
export interface ProductModel {
id: string;
name: string;
caption?: string;
description?: string;
active?: boolean;
images?: string[];
price?: string | number | null;
recurring?: {
interval: string,
interval_count: number
},
metadata?: object
}
export class ProductModel implements ProductModel {
constructor(productData?: ProductModel) {
if (productData) {
Object.assign(this, productData);
}
}
}
NB: I have a utility function called respond that standarizes our API responses. You can just res.send the response
Read ttmarek's answer first. However, note that the pages do not seem to provide a full example if you need all the answers. From "List all Prices":
Each entry in the array is a separate price object. If no more prices
are available, the resulting array will be empty.
As it states, and is also stated here and in the docs, to get all of them, you need to loop until the resulting array is empty....
Here is some code that will get you all the products and all the prices...
import stripe
stripe.api_key = stripe_test_private_key
def get_all_stripe_objects(stripe_listable):
objects = []
get_more = True
starting_after = None
while get_more:
#stripe.Customer implements ListableAPIResource(APIResource):
resp = stripe_listable.list(limit=100,starting_after=starting_after)
objects.extend(resp['data'])
get_more = resp['has_more']
if len(resp['data'])>0:
starting_after = resp['data'][-1]['id']
return objects
all_stripe_products = get_all_stripe_objects(stripe.Product)
all_stripe_prices = get_all_stripe_objects(stripe.Price)

react-table not rendering server-side data in table (with manual pagination, filtering & sorting)

I'm having trouble getting data from the backend (Python API) to show in react-table manually. I've read the documentation and I'm trying to use the example here: https://react-table.js.org/#/story/server-side-data
I'm only seeing data in one column and only for 6 records which is really weird. It's probably the way I'm mixing in async/await syntax with the example code which uses a promise. I was able to create a simple react-table fetching data with the same async/await syntax, but when I added the server-side data code from the example (the requestData function) it wouldn't work.
I've spent days on this and looking all over Stackoverflow and the internet. I'm a newbie so please go easy on me. Here's what I have:
import React from 'react'
import { render } from 'react-dom'
import ReactTable from 'react-table'
import api from 'src/api'
import { orderBy } from 'lodash'
// importing react-table css would not work so I added it using cdn link
const requestData = async (pageSize, page, sorted, filtered) => {
// api is a wrapper for axios.create()
const rawData = await api.admin.exercise.feed()
return new Promise((resolve, reject) => {
let filteredData = rawData;
if (filtered.length) {
filteredData = filtered.reduce((filteredSoFar, nextFilter) => {
return filteredSoFar.filter(row => {
return (row[nextFilter.id] + "").includes(nextFilter.value);
});
}, filteredData);
}
const sortedData = orderBy(
filteredData,
sorted.map(sort => {
return row => {
if (row[sort.id] === null || row[sort.id] === undefined) {
return -Infinity;
}
return typeof row[sort.id] === "string"
? row[sort.id].toLowerCase()
: row[sort.id];
};
}),
sorted.map(d => (d.desc ? "desc" : "asc"))
);
const res = {
rows: sortedData.slice(pageSize * page, pageSize * page + pageSize),
pages: Math.ceil(filteredData.length / pageSize)
};
resolve(res);
});
};
export class ExerciseList extends React.Component {
constructor() {
super();
this.state = {
data: [],
pages: null,
loading: true
};
this.fetchData = this.fetchData.bind(this);
}
setLoading(loading) {
this.setState({ loading })
}
fetchData(state, instance) {
this.setLoading(true);
requestData(
state.pageSize,
state.page,
state.sorted,
state.filtered
).then(res => {
this.setState({
data: res.rows,
pages: res.pages,
loading: false
});
});
}
render() {
const { data, pages, loading } = this.state;
return (
<div>
<ReactTable
columns={[
{
Header: "Name",
accessor: "name"
},
{
Header: "Movement",
accessor: "movement"
},
{
Header: "Equipment",
accessor: "equipments"
},
{
Header: "Channel",
accessor: "channel"
},
{
Header: "Level",
accessor: "skill_level"
},
{
Header: "Duration",
accessor: "duration",
filterable: false
},
{
Header: "Injuries",
accessor: "injuries"
},
{
Header: "Is Substitute",
accessor: "has_video",
Cell: ({ value }) => (value? 'Yes': 'No'),
filterable: false
}
]}
data={data}
pages={pages}
loading={loading}
onFetchData={this.fetchData}
manual
filterable
defaultPageSize={10}
className="-striped -highlight"
/>
</div>
);
}
}
render(<ExerciseList />, document.getElementById('datatable'));
Please refer the link for server-side sorting, pagination and manual filtering within the grid
// Component related to methods for sorting, pagination server side and filtering manual filtering with in the grid
import React from 'react'
import 'react-table/react-table.css'
import ReactTable from 'react-table'
import autoBind from 'react-autobind'
import {filterCaseInsensitive} from '../../helper/commonMethods'
class ServerSideAtomGrid extends React.Component {
super(props)
const userDetails = getUserDetails()
this.state = {
page: 0,
pageSizeOptions: [500, 1000, 2000, 4000],
pageSize: 500,
totalRecords: 0,
nextCursor: '*',
cursorList: [{
page: 0,
cursor: '*'
}],
sortFields: {
field: 'created_dtm',
sort: 'desc'
},
columnData,
}
autoBind(this)
}
handlePageChange (page) {
const pageNumber = (page)
const cursorList = this.state.cursorList
let cusrsorMark = ''
_.each(cursorList, (list) => {
if (list.page === pageNumber) {
cusrsorMark = list.cursor
}
})
this.setState({
nextCursor: cusrsorMark,
page: pageNumber
}, () => this.searchData(cusrsorMark, pageNumber))
}
handleSizePerPageChange (pageSize) {
this.resetData(pageSize)
this.searchData('*', 0)
}
handleSorting = (state, instance) => {
const sorted = state
let field = 'created_dtm'
let sort = 'desc'
sorted && sorted.length > 0 && sorted.map(fld => {
field = fld.id
sort = fld.desc ? 'desc' : 'asc'
})
this.setState({
sortFields: {
field,
sort
}
}, () => this.searchData('*', 0))
}
////
searchData('*', 0) {
//Axios call you cna have
}
filterCaseInsensitive (filter, row) {
const id = filter.pivotId || filter.id
return row[id] ? row[id].toString().toLowerCase().includes(filter.value.toLowerCase()) : true
}
render () {
const {
classes, gridData, gridColumns, defaultFilter, totalRecords,
gridPageSizeOptions, gridPage, gridPages, gridPageSize, gridLoading
} = this.props
return (
<div>
<ReactTable
columns={gridColumns}
data={gridData}
onSortedChange={(state, instance) => {
this.handleSorting(state, instance)
}}
filterable={defaultFilter}
defaultFilterMethod={filterCaseInsensitive}
noDataText="Ops No result found!"
defaultPageSize={this.state.pageSize}
className="-highlight"
style={{height: `${totalRecords < 25 ? '' : `800px`}`, width: '100%', textAlign: 'center'}}
pageText={`Total Count : ${totalRecords.toLocaleString()} Page: `}
loading={gridLoading}
page={this.state.page}
pages={this.state.pages}
showPaginationTop
pageSize={this.state.pageSize}
pageSizeOptions={gthis.state.pageSizeOptions}
minRows={25}
manual
onPageChange={page => {
this.setState({page})
this.handlePageChange(page)
}}
onPageSizeChange={(pageSize, page) => {
this.setState({
page,
pageSize
})
this.props.handleSizePerPageChange(pageSize)
}}
showPageJump={false}
/>
</div>
)
}
}
export default (ServerSideAtomGrid)
My Fiddle: https://jsfiddle.net/gowthamguruju/o9ybxqaj/8/

No row returned when querying a couchbase view with python

I'm trying to query a view from the python sdk but I have no row returned.
My map function is :
function (doc, meta) {
if (doc.EXENUM_A !== null)
{
if (doc.PRS != null) {
emit(doc.EXENUM_A, doc.PRS);
}
}
}
The reduce one is :
function (keys, values) {
for (k in keys) {
result = {};
for (v in values) {
if (!(values[v] in result)) {
result[values[v]] = 0;
}
result[values[v]] += 1;
}
return [keys[k], result];
}
}
When I execute this query in the couchbase webui, i have the expected result.
But when I try to query it from python, i have an empty resultset :
from couchbase.bucket import Bucket
from couchbase.views.iterator import View
import os
import fnmatch
cb=Bucket('couchbase://172.17.0.2:8091/my_db', password="my_password")
view = View(cb, "dev_testview", "by_num", limit=10,reduce=True)
for row in view:
print(row.key)
Have I missed something ?
This view is still a dev_view. Do I have to publish it in production before I can query it from python ?
I found the answer. It comes from parameters i had to add
view = View(cb, "dev_testview", "by_num", limit=10, reduce=True, group=True, inclusive_end=False)

Categories