How to set multiple keys and relations for DataLoader with TypeORM? - graphql

OneToOne case
For one JoinColumn key in TypeORM, the #Extensions below can work with loader and loadkey.
But in this case, there are two JoinColumn keys: postId and version. How to set them into #Extensions?
#OneToOne(() => PostVersion, {
lazy: true,
cascade: true,
createForeignKeyConstraints: false,
})
#JoinColumn([
{ name: 'id', referencedColumnName: 'postId' },
{ name: 'version', referencedColumnName: 'version' },
])
#Field(() => PostVersion, {
middleware: [dataloaderFieldMiddleware],
})
// How to set both postId and version keys below?
#Extensions({
loader: (dataloaders: IDataloaders) => dataloaders.currentPostVersion,
loadKey: (post: Post) => post.id,
})
current: Promise<PostVersion>;
ManyToMany case
For many to many relation, one side can set #Extensions with one key. Is it right to set the other relation key on the other side in #Extensions?
#ManyToMany(() => Type)
#JoinTable({
name: 'types_posts',
joinColumn: {
name: 'post_id',
referencedColumnName: 'id',
},
inverseJoinColumn: {
name: 'type_id',
referencedColumnName: 'id',
},
})
#Field(() => [Type], {
middleware: [dataloaderFieldMiddleware],
})
// How to set many to many relations keys with dataloader here?
#Extensions({
loader: (dataloaders: IDataloaders) => dataloaders.typeByPostId,
loadKey: (post: Post) => post.id,
})
postboards: Promise<Type[]>;

Related

store results from method in data form

I am going to preface this with I have NOT done this in a LONG time and my mind is mud. So no picking on me just remind me what I am doing wrong or not remembering.
NOTE: This is VueJS 3 / Tailwind 3 inside a Laravel 9 Jetstream Project
I have a method...
locatorButtonPressed() {
navigator.geolocation.getCurrentPosition(
position => {
console.log(position.coords.latitude);
console.log(position.coords.longitude);
},
error => {
console.log(error.message);
},
)
},
and I have a form data
data() {
return {
form: this.$inertia.form({
name: '',
email: '',
password: '',
password_confirmation: '',
birthdate: '',
user_latitude: '',
user_longitude: '',
user_city: '',
user_region: '',
user_country: '',
location: '',
terms: false,
})
}
}
I want to store position.coords.latitude and position.coords.longitude from the method in the form Data under user_latitude and user_longitude respectfully.
What am I forgetting???
The data properties can be accessed via this.PROPERTY_NAME. For example, to set form.user_latitude, use this.form.user_latitude = newValue.
export default {
methods: {
locatorButtonPressed() {
navigator.geolocation.getCurrentPosition(
position => {
this.form.user_latitude = position.coords.latitude;
this.form.user_longitude = position.coords.longitude;
})
},
}
}
demo

How to search through JSON response with Cypress assertions

Considering the below API response I would like to assert the exact location of a certain value in a JSON structure. In my case the name of pikachu within forms:
"abilities": [
{
"ability": {
"name": "lightning-rod",
"url": "https://pokeapi.co/api/v2/ability/31/"
},
"is_hidden": true,
"slot": 3
},
{
"ability": {
"name": "static",
"url": "https://pokeapi.co/api/v2/ability/9/"
},
"is_hidden": false,
"slot": 1
}
],
"base_experience": 112,
"forms": [
{
"name": "pikachu",
"url": "https://pokeapi.co/api/v2/pokemon-form/25/"
}]
I would like to extend below code snippet to not scan the entire body as a whole as there are a lot of name's in the response, but rather go via forms to exactly pinpoint it:
describe('API Testing with Cypress', () => {
var baseURL = "https://pokeapi.co/api/v2/pokemon"
beforeEach(() => {
cy.request(baseURL+"/25").as('pikachu');
});
it('Validate the pokemon\'s name', () => {
cy.get('#pikachu')
.its('body')
.should('include', { name: 'pikachu' })
.should('not.include', { name: 'johndoe' });
});
Many thanks in advance!
Getting to 'forms' is just a matter of chaining another its(), but the 'include' selector seems to require an exact match on the object in the array.
So this works
it("Validate the pokemon's name", () => {
cy.get("#pikachu")
.its("body")
.its('forms')
.should('include', {
name: 'pikachu',
url: 'https://pokeapi.co/api/v2/pokemon-form/25/'
})
})
or if you just have the name,
it("Validate the pokemon's name", () => {
cy.get("#pikachu")
.its("body")
.its('forms')
.should(items => {
expect(items.map(i => i.name)).to.include('pikachu')
})
})
and you can assert the negative,
.should(items => {
expect(items.map(i => i.name)).to.not.include('johndoe')
})
Can you try the below code and see if it helps with your expectation. From the response you could get the name as below;
describe('API Testing with Cypress', () => {
var baseURL = "https://pokeapi.co/api/v2/pokemon"
beforeEach(() => {
cy.request(baseURL+"/25").as('pikachu');
});
it('Validate the pokemon\'s name', () => {
cy.get('#pikachu').then((response)=>{
const ability_name = response.body.name;
expect(ability_name).to.eq("pikachu");
})
});
})

How to parse slug from url using route of laravel to vue components

I want to parse data to show product by using slug from laravel show route resource (get) to vue js components by using laravel api
example: https://shop.app/product/slug-name
i want to parse the slug-name into the vue components
export default {
name: 'product',
mounted() {
// console.log('Component mounted.')
this.fetchData()
},
data(){
return{
products: [],
product: {
id: '',
name: '',
slug: '',
description: '',
image: '',
created_at: '',
updated_at: ''
}
}
},
methods: {
fetchData(){
axios.get('/api/products')
.then((res) => {
this.products = res.data
})
.catch((err) => {
console.log(err)
})
}
}
}
i expect the output from showing the slug name, not show all the products
You can get you current url by
let currentUrl = window.location.pathname;
and then you can use lodash library its already included in laravel if you see you boostrap.js file
let ar = _.split(currentUrl, '/');
it will return your array. its just like explode in php. you can read about this here
and at last, get your product by
this.productName = _.last(ar);
`_.last` Its will just give you last element of your array which is your product. [here][2] is the documentation
you can make a method for this. like below
getProductSlug(){
let currentUrl = window.location.pathname;
let ar = _.split(currentUrl, '/');
return _.last(ar);
},
If you are using Laravel Routes you can get your slug in to your Vue instance like
var slugName = '{{ $slug }}';
export default {
name: 'product',
methods: {
fetchData(){
//you can use slugNname here
axios.get('/api/products/' + slugName)
.then((res) => {
this.products = res.data
})
.catch((err) => {
console.log(err)
})
}
}
after that you can use slugName in your axios request
hope it helps

Centralizing Post Data on the client and server

I'm building my first API and I have this nightmare scenario where I see myself defining the same request data in multiples places. How are people maintaining their key/value payloads?
Here's my VueJS component on the client side:
<script>
export default {
data() {
return {
name: '',
description: '',
selectedHeader: '',
}
},
computed: {
businessUrl() {
return this.name.replace(/[^A-Z0-9]+/ig, '') + '.test.com';
},
},
methods: {
preview() {
let data = {
'name': this.businessUrl,
'description' : this.description,
'selectedHeader': this.selectedHeader
};
axios.post('/builder/preview', data)
...
</script>
Server-side:
public function preview()
{
$validatedData = request()->validate([
'name' => 'required',
'description' => 'string',
'selectedHeader' => 'required',
]);
$business = new Business;
$business->name = request('name');
$business->description = request('description');
$business->header = request('selectedHeader');
return view('business', compact('business'));
}
If I want to change the 'name' field that is posted on my route I have to do it in up to 5 places if I include references in my HTML. Any patterns that people have developed to avoid this duplication?

What is Expect function to validate schema in JEST and Supertest?

like in chakram testing expect(WallObject).to.have.schema(expectedSchema). Similarly which function is there in Jest? I am using jest with supertest.
There is nothing available in JEST to test schema directly. I have achieved this with the help of AJV. Using AJV i am comparing schema with response and then using Jest expect checking value is true or not. like
const Ajv = require('ajv');
const ajv = new Ajv({
allErrors: true,
format: 'full',
useDefaults: true,
coerceTypes: 'array',
errorDataPath: 'property',
sourceCode: false,
});
const validateParams = (params, schema) => {
const validate = ajv.compile(schema);
const isValidParams = validate(params);
return isValidParams;
};
const result = validateParams(res.body, {
type: 'array',
items: {
type: 'object',
properties: {
id: {
type: 'integer',
},
email: {
type: 'string',
},
}
}
});
expect(result).toBe(true);
done();

Resources