How to query a specific node using Graphql? - javascript

I am trying to use Graphql to return a specific instance of an object.
This is my Graphql query:
query MyQuery {
allContentfulFlexStyleBody {
edges {
node {
image {
file {
url
}
}
}
}
}
}
It returns 3 Nodes:
{
"data": {
"allContentfulFlexStyleBody": {
"edges": [
{
"node": {
"image": {
"file": {
"url": "//images.ctfassets.net/m7ipc0qjqa17/6JTBUN3mkENLvEVuC/6ff4b2da441f1c7cec2eb401534aa749/-19.jpeg"
}
}
}
},
{
"node": {
"image": {
"file": {
"url": "//images.ctfassets.net/m7ipc0qjqa17/2s6lg5oBJ7F780DI1/b4068dcc9cc889dbcd09ed992793e771/-BTS.png"
}
}
}
},
{
"node": {
"image": {
"file": {
"url": "//images.ctfassets.net/m7ipc0qjqa17/6bRRjlI1nLFCdUawZ/12af617d352b21864192dcc033198951/MyStylist_Photo_Grid_Layout__Retouched_Photos_Shortlist-6.jpeg"
}
}
}
}
]
}
},
"extensions": {}
}
I am attempting to display one image within my gatsby project as such:
{data.allContentfulFlexStyleBody.edges.map(({ node }, index) => (
<img
className={"contentFeatureImg"}
alt={``}
key={``}
src={node.image.file.url}
/>
))}
All images are being displayed. How do I access the first, second or third node exclusively without returning the entire edges array?

Accessing a specific element of the edges array works enough for what I'm doing here:
<img
className={"contentFeatureImg1"}
alt={``}
key={``}
src={data.allContentfulFlexStyleBody.edges[0].node.image.file.url}
/>

Related

JS How to find result in nested objects [duplicate]

This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Closed 8 months ago.
The community reviewed whether to reopen this question 8 months ago and left it closed:
Original close reason(s) were not resolved
I have a nested Object that I need to iterate. The object looks like this:
{
"Page1": {
"path": "/page1"
},
"Page2": {
"path": "/account/menu/page1"
},
"Page3": {
"items": {
"Subpage1": {
"path": "/account/menu/subpage1"
},
"Subpage2": {
"path": "/account/menu/subpage2"
},
"Subpage3": {
"path": "/account/menu/subpage3"
}
}
},
"Page4": {
"items": {
"Subpage4": {
"path": "/account/menu/subpage4"
},
"Subpage5": {
"path": "/account/menu/subpage5"
},
...
I need to get the name of the specific subpage, based on the path of the user.
For example. If the user is on the page /account/menu/subpage2. I need to get the name Subpage2.
What I did is the following:
const currentPageName = getPageName(this.props?.match?.params.menu); //This function gets the name of the current page (Subpage2)
const getThePageName = = path => Object.keys(jsonData).find(el => jsonData[el]?.items && jsonData[el]?.items[currentPageName]?.path === path)
console.log("getThePageName", getThePageName("/account/menu/subpage2")));
The result of the above is Page3, but I need it to be Subpage2. What am I doing wrong and how to fix it?
Concept
Iterate through all the data entries and check if the path of any of these pages equal to the target path specified. Also within the loop, iterate through all of the pages' subpages and, again, check if the path of any of these subpages equal to the target path specified. If a match found then return the result as the key of the path's object.
Code
const data = {"Page1":{"path":"/page1"},"Page2":{"path":"/account/menu/page1"},"Page3":{"items":{"Subpage1":{"path":"/account/menu/subpage1"},"Subpage2":{"path":"/account/menu/subpage2"},"Subpage3":{"path":"/account/menu/subpage3"}}},"Page4":{"items":{"Subpage4":{"path":"/account/menu/subpage4"},"Subpage5":{"path":"/account/menu/subpage5"}}}};
function findPage(data,target){
let result;
Object.entries(data).forEach(page => {
if (page[1].path === target) result = page[0];
if (page[1].items){
Object.entries(page[1].items).forEach(subpage => {
if (subpage[1].path === target) result = subpage[0];
});
}
});
return result;
}
console.log(findPage(data,"/account/menu/subpage2"));
console.log(findPage(data,"/page1"));
Solution using recursion, can work with deeper level of "sub pages".
const data = { "Page1": { "path": "/page1" }, "Page2": { "path": "/account/menu/page1" }, "Page3": { "items": { "Subpage1": { "path": "/account/menu/subpage1" }, "Subpage2": { "path": "/account/menu/subpage2" }, "Subpage3": { "path": "/account/menu/subpage3" } } }, "Page4": { "items": { "Subpage4": { "path": "/account/menu/subpage4" }, "Subpage5": { "path": "/account/menu/subpage5" }, "Subpage6": { "items": { "Subsubpage1": { "path": "/secret" } } } } } };
function getPageNameForPath(data, path) {
for (const pageName in data) {
if (data[pageName].path != null) {
if (data[pageName].path === path) {
return pageName;
}
} else {
const found = getPageNameForPath(data[pageName].items, path);
if (found) {
return found;
}
}
}
}
console.log(getPageNameForPath(data, '/account/menu/subpage2'));
console.log(getPageNameForPath(data, '/account/menu/page1'));
console.log(getPageNameForPath(data, '/secret'));
here is some piece of code
const jsonData = { "Page1": { "path": "/page1" }, "Page2": { "path": "/account/menu/page1" }, "Page3": { "items": { "Subpage1": { "path": "/account/menu/subpage1" }, "Subpage2": { "path": "/account/menu/subpage2" }, "Subpage3": { "path": "/account/menu/subpage3" } } }, "Page4": { "items": { "Subpage4": { "path": "/account/menu/subpage4" }, "Subpage5": { "path": "/account/menu/subpage5" }, } } };
const currentPageName = 'Subpage2';
const getThePageName = path => Object.keys(jsonData).reduce((acc, el) => {
if (acc?.length) {
return acc;
}
if (jsonData[el].hasOwnProperty('items')) {
if (jsonData[el]?.items?.[currentPageName]?.path === path) {
console.log(path, jsonData[el]?.items?.[currentPageName]?.path)
acc = currentPageName;
}
} else {
if (jsonData[el].path === path) {
console.log(path, jsonData[el].path, path)
acc = el;
}
}
return acc;
}, undefined);
console.log("getThePageName", getThePageName("/account/menu/subpage2"));

how to fetch only specific data from graphql query

I am trying to fetch some data from my CMS but I am facinf an error when fetching a specific data.
It's an array that I want to fetch with the graphql query :
{
allPrismicLastPosts {
nodes {
data {
links {
blog {
document {
... on PrismicBlog {
data {
post_img {
url
}
post_title {
text
}
post_paragraph {
text
}
tag
}
}
... on PrismicCulture {
data {
tag
culture_image {
url
}
culture_paragraph {
text
}
culture_title {
text
}
}
}
}
}
}
}
}
}
}
This is it JSON Format :
"links": [
{
"blog": {
"document": {
"data": {
"post_img": {
"url": "https://images.prismic.io/zinee/67254822-5c44-42fe-8d5b-7f500141c3a7_Mask%20Group%20(1).png?ixlib=gatsbyFP&auto=compress%2Cformat&fit=max"
},
"post_title": {
"text": "Make more time for the work that matters most using our services"
},
"post_paragraph": {
"text": "A lot of different components that will help you create the perfect look"
},
"tag": "Fiction"
}
}
}
},
{
"blog": {
"document": {
"data": {
"post_img": {
"url": "https://images.prismic.io/zinee/4898e2a8-ebfb-41d4-b843-550e9d9c84da_Mask%20Group.png?ixlib=gatsbyFP&auto=compress%2Cformat&fit=max"
},
"post_title": {
"text": "Make myspace your best designed space"
},
"post_paragraph": {
"text": "A lot of different components that will help you create the perfect look"
},
"tag": "Fiction"
}
}
}
},
{
"blog": {
"document": {
"data": {
"post_img": {
"url": "https://images.prismic.io/zinee/67254822-5c44-42fe-8d5b-7f500141c3a7_Mask%20Group%20(1).png?ixlib=gatsbyFP&auto=compress%2Cformat&fit=max"
},
"post_title": {
"text": "Make more time for the work that matters most using our services"
},
"post_paragraph": {
"text": "A lot of different components that will help you create the perfect look"
},
"tag": "Fiction"
}
}
}
},
{
"blog": {
"document": {
"data": {
"post_img": {
"url": "https://images.prismic.io/zinee/4898e2a8-ebfb-41d4-b843-550e9d9c84da_Mask%20Group.png?ixlib=gatsbyFP&auto=compress%2Cformat&fit=max"
},
"post_title": {
"text": "Make myspace your best designed space"
},
"post_paragraph": {
"text": "A lot of different components that will help you create the perfect look"
},
"tag": "Fiction"
}
}
}
}
]
I get a Cannot read properties of undefined (reading 'text') error when I fetch it like this :
{post.data.links.map((test)=>
(
<>
<h1>{test.blog.document.data.post_paragraph.text}</h1>
</>
))}
But when I try to fetch like this it works:
{post.data.links.map((test)=>
(
<>
<h1>{test.blog.document.data.tag}</h1>
</>
))}
Any idea how to fix this please ?
the tag field works and get fetched perfectly but with data like : post_paragraph.text or title.text doesn't work !!
Your GraphQL fragment PrismicBlog has post_paragraph which has text (so your loop works) however, when it's mapping PrismicCulture fragment, where the structure differs, your map breaks because there's no such property, in PrismicCulture it's called culture_paragraph with a text property in it.
If you are trying to map both fragments in one loop I'd suggest using the same data structure in the CMS, changing culture_paragraph for post_paragraph so your loop will be valid.
If that's not an option, you can use GraphQL alias to map your culture_paragraph into post_paragraph such as:
{
allPrismicLastPosts {
nodes {
data {
links {
blog {
document {
... on PrismicBlog {
data {
post_img {
url
}
post_title {
text
}
post_paragraph {
text
}
tag
}
}
... on PrismicCulture {
data {
tag
culture_image {
url
}
post_paragraph: culture_paragraph {
text
}
culture_title {
text
}
}
}
}
}
}
}
}
}
}
Note the post_paragraph: culture_paragraph alias.
Another alternative is using the optional chaining to only print the text if the structure matches the loop:
{post.data.links.map((test)=>
(
<>
<h1>{test.blog.document?.data?.post_paragraph?.text}</h1>
</>
))}

Implementing GraphQL Global Object Identification in NestJS (code-first approach)

I am trying to implement Global Object Identification described in GraphQL's documentation in NestJS.
1.) I started by creating a Node interface:
import { ID, InterfaceType, Field } from '#nestjs/graphql'
#InterfaceType()
export abstract class Node {
#Field(type => ID)
id: number
}
2.) I implemented it in my model:
import { Table } from "sequelize-typescript";
import { ObjectType } from "#nestjs/graphql";
import { Node } from "src/node/node-interface";
#ObjectType({
implements: Node
})
#Table
export class User extends Model {
// [Class body here...]
}
3.) Then I created a Query that would return users:
import { Resolver, Query} from "#nestjs/graphql";
import { User } from "./user-model";
#Resolver(of => User)
export class UserResolver {
#Query(returns => [Node])
async users() {
let users = await User.findAll();
console.log(users);
return users;
}
}
4.) Then I performed the test query from the documentation:
{
__schema {
queryType {
fields {
name
type {
name
kind
}
args {
name
type {
kind
ofType {
name
kind
}
}
}
}
}
}
}
5.) But instead of receiving the proper response:
{
"__schema": {
"queryType": {
"fields": [
// This array may have other entries
{
"name": "node",
"type": {
"name": "Node",
"kind": "INTERFACE"
},
"args": [
{
"name": "id",
"type": {
"kind": "NON_NULL",
"ofType": {
"name": "ID",
"kind": "SCALAR"
}
}
}
]
}
]
}
}
}
6.) I get this:
{
"data": {
"__schema": {
"queryType": {
"fields": [
{
"name": "users",
"type": {
"name": null,
"kind": "NON_NULL"
},
"args": []
}
]
}
}
}
}
I have no clue what I am doing wrong. I'd appreciate any help with this.
Maybe it's too late, but I'm at Node Resolver node must be nullable
import * as GQL from '#nestjs/graphql';
#GQL.Resolver(() => Node, {})
export class NodeResolver {
#GQL.Query(() => Node, {
name: 'node',
defaultValue: [],
nullable: true,
})
node(
#GQL.Args('id', { type: () => GQL.ID } as GQL.ArgsOptions)
id: Scalars['ID'],
): Promise<Node> {
// Implement
return null;
}
}
result:
{
"name": "node",
"type": {
"name": "Node",
"kind": "INTERFACE",
},
"args": [
{
"name": "id",
"type": {
"kind": "NON_NULL",
"ofType": {
"name": "ID",
"kind": "SCALAR"
}
}
}
]
},

Creating Video or GIF or time lapse from an array of image URLs

I have got a list of image url form an api endpoint, and i wish to generate a video with these images in javascript.
after the video is created i'd display it on the page, im using react btw.
images = [
"https://some-bucket.s3.amazonaws.com/demo/0173.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0126.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0160.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0184.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0177.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0166.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0174.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0167.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0187.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0197.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0190.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0192.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0189.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0188.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0182.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0198.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0196.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0163.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0117.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0199.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0191.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0148.jpg",
"https://some-bucket.s3.amazonaws.com/demo/0132.jpg"
]
I think what you might be looking for is the Transloadit /video/merge robot. For example, this template here will take all of the files uploaded and then convert them into an animated gif in order to be exported to an Amazon S3 bucket.
{
"steps": {
":original": {
"robot": "/upload/handle"
},
"animated": {
"robot": "/video/merge",
"use": {
"steps": [
{
"name": ":original",
"as": "image"
}
]
},
"result": true,
"duration": 7.8,
"framerate": "10",
"ffmpeg_stack": "v4.3.1",
"ffmpeg": {
"f": "gif",
"pix_fmt": "rgb24"
},
"resize_strategy": "pad"
},
"exported": {
"use": [
":original",
"animated"
],
"robot": "/s3/store",
"credentials": "YOUR_AWS_CREDENTIALS",
"url_prefix": "https://demos.transloadit.com/"
}
}
}
While, transloadit doesn't have native react integration, it can be used through uppy's robodog service. Here's a small React snippet that will take an array of files, run it through a specified template, and then output an array of results, using the template from before.
import Uppy from '#uppy/core'
import { Dashboard } from '#uppy/react'
import { Transloadit } from '#uppy/transloadit'
import '#uppy/core/dist/style.css'
import '#uppy/dashboard/dist/style.css'
const url_list = ["www.link1.com/image.png", "www.link2.com/image.png", "www.link3.com/image.png"]
const uppy = new Uppy()
.use(Transloadit, {
params: {
"auth": {
"key": "YOUR_TRANSLOADIT_AUTH_KEY"
}
"steps": {
"imported": {
"robot": "/http/import",
"url": url_list
},
"animated": {
"robot": "/video/merge",
"use": {
"steps": [
{
"name": "imported",
"as": "image"
}
]
},
"result": true,
"duration": 7.8,
"framerate": "10",
"ffmpeg_stack": "v4.3.1",
"ffmpeg": {
"f": "gif",
"pix_fmt": "rgb24"
},
"resize_strategy": "pad"
},
"exported": {
"use": [
"imported",
"animated"
],
"robot": "/s3/store",
"credentials": "YOUR_AWS_CREDENTIALS",
"url_prefix": "https://demos.transloadit.com/"
}
}
}
});
uppy.on("complete", (result) => {
console.log("Upload complete! We've uploaded these files: ", result.successful)
})
export default function Home() {
return (
<div className="container">
<Dashboard
uppy={uppy}
/>
</div>
)
}

How to get the value of a deep nested json object?

I'm working on an app in javascript, and I have this json object (this is a simplified example of the actual json object)
{
"data": [
"user": {
"pictures"{
"sizes"[
0: {
"link": "http://www"
},
1: {
"link": "http://"
}
]
}
}
]
}
And I want to get the value of link, so i tried data.user.pictures.sizes[0].link, and it returned an error. How to get the right value?
edit: I'm using a map function to loop around the data object, so i can display values in an html page. it works for most of the other items, except for pictures sizes, i cant seem to get the value of the second item in the sizes array.
From the data, it shows that 'data' contains array and sizes contains array that contains object of properties 0 and 1 , so do this
data[0].user.pictures.sizes[0].0.link
First of all you need to have colons to "pictures" and "sizes" :)
Secondly, it depends what your structure is.
for example:
if you need to use arrays as they appear in your example:
var a = {
"data": [
{
"user": {
"pictures": {
"sizes": [
{
0: {
"link": "http://www"
}
},
{
1: {
"link": "http://"
}
}
]
}
}
}
]
}
console.log(a.data[0].user.pictures.sizes[0][0].link);
or you just need a json without arrays in it:
var b = {
"data": {
"user": {
"pictures": {
"sizes": {
0: {
"link": "http://www"
},
1: {
"link": "http://"
}
}
}
}
}
}
console.log(b.data.user.pictures.sizes[0].link);
or you can even mix them:
var c = {
"data": {
"user": {
"pictures": {
"sizes": [
{
"link": "http://www"
},
{
"link": "http://"
}
]
}
}
}
}
console.log(c.data.user.pictures.sizes[0].link);
notice the subtle difference of "sizes" in b and c and the double array of a. This is because json with index as keys is the same as an array. check this example:
var example = [
{
0: "example00",
1: "example01",
2: "example02"
},
{
0: "example10",
1: "example11",
2: "example12"
},
]
console.log(example[0][1]); // == example01
you can see that you have 2 arrays within the example array
hope that helps :)
Your JSON is wrong, it should be as below :
var js = {
"data": {
"user":{
"pictures":{
"sizes":[
{
"link":"http://www"
},
{
"link":"http://"
}
]
}
}
}
}
To get the value:
js.data.user.pictures.sizes[0].link

Categories

Resources