Shopify Product Variant
This page documents the Shopify Product Variant model.
Data Shape
Gadget's database stores Shopify Product Variant records by storing and retrieving each of the fields defined on the model in the Gadget Editor to a managed database. Gadget has generated a GraphQL type matching the configured fields for Shopify Product Variant:
1export interface ShopifyProductVariant {2 __typename: "ShopifyProductVariant";34 /** The globally unique, unchanging identifier for this record. Assigned and managed by Shopify. */5 id: Scalars["GadgetID"];67 /** The time at which this record was first created. Set once upon record creation and never changed. Managed by Gadget. */8 createdAt: Scalars["DateTime"];910 /** The time at which this record was last changed. Set each time the record is successfully acted upon by an action. Managed by Gadget. */11 updatedAt: Scalars["DateTime"];1213 /** The current state this record is in. Changed by invoking actions. Managed by Gadget. */14 state: Scalars["RecordState"];1516 barcode: Scalars["String"] | null;1718 compareAtPrice: Scalars["String"] | null;1920 fulfillmentService: Scalars["String"] | null;2122 grams: Scalars["Float"] | null;2324 inventoryManagement: Scalars["String"] | null;2526 inventoryPolicy: Scalars["String"] | null;2728 productImage: ShopifyProductImage | null;2930 productImageId: Scalars["GadgetID"] | null;3132 inventoryQuantity: Scalars["Float"] | null;3334 inventoryQuantityAdjustment: Scalars["Float"] | null;3536 oldInventoryQuantity: Scalars["Float"] | null;3738 option1: Scalars["String"] | null;3940 option2: Scalars["String"] | null;4142 option3: Scalars["String"] | null;4344 position: Scalars["Float"] | null;4546 presentmentPrices: Scalars["JSON"] | null;4748 price: Scalars["String"] | null;4950 requiresShipping: Scalars["Boolean"] | null;5152 product: ShopifyProduct | null;5354 productId: Scalars["GadgetID"] | null;5556 shopifyCreatedAt: Scalars["DateTime"] | null;5758 sku: Scalars["String"] | null;5960 taxCode: Scalars["String"] | null;6162 shopifyUpdatedAt: Scalars["DateTime"] | null;6364 taxable: Scalars["Boolean"] | null;6566 title: Scalars["String"] | null;6768 weight: Scalars["Float"] | null;6970 weightUnit: Scalars["String"] | null;7172 shop: ShopifyShop | null;7374 shopId: Scalars["GadgetID"] | null;7576 results: ResultConnection;7778 /** Get all the fields for this record. Useful for not having to list out all the fields you want to retrieve, but slower. */79 _all: Scalars["JSONObject"];80}
1type ShopifyProductVariant {2 """3 The globally unique, unchanging identifier for this record. Assigned and managed by Shopify.4 """5 id: GadgetID!67 """8 The time at which this record was first created. Set once upon record creation and never changed. Managed by Gadget.9 """10 createdAt: DateTime!1112 """13 The time at which this record was last changed. Set each time the record is successfully acted upon by an action. Managed by Gadget.14 """15 updatedAt: DateTime!1617 """18 The current state this record is in. Changed by invoking actions. Managed by Gadget.19 """20 state: RecordState!21 barcode: String22 compareAtPrice: String23 fulfillmentService: String24 grams: Float25 inventoryManagement: String26 inventoryPolicy: String27 productImage: ShopifyProductImage28 productImageId: GadgetID29 inventoryQuantity: Float30 inventoryQuantityAdjustment: Float31 oldInventoryQuantity: Float32 option1: String33 option2: String34 option3: String35 position: Float36 presentmentPrices: JSON37 price: String38 requiresShipping: Boolean39 product: ShopifyProduct40 productId: GadgetID41 shopifyCreatedAt: DateTime42 sku: String43 taxCode: String44 shopifyUpdatedAt: DateTime45 taxable: Boolean46 title: String47 weight: Float48 weightUnit: String49 shop: ShopifyShop50 shopId: GadgetID51 results(52 """53 Returns the items in the list that come after the specified cursor.54 """55 after: String5657 """58 Returns the first n items from the list.59 """60 first: Int6162 """63 Returns the items in the list that come before the specified cursor.64 """65 before: String6667 """68 Returns the last n items from the list.69 """70 last: Int7172 """73 A list of sort orders to return the results in74 """75 sort: [ResultSort!]7677 """78 A list of filters to refine the results by79 """80 filter: [ResultFilter!]8182 """83 A free form text search query to find records matching84 """85 search: String86 ): ResultConnection!8788 """89 Get all the fields for this record. Useful for not having to list out all the fields you want to retrieve, but slower.90 """91 _all: JSONObject!92}
You can preview what a real record's shape looks like by fetching it using the alida-quiz-app-2 API Playground.
Any fetched Shopify Product Variant record will have this same ShopifyProductVariant
type, and expose the same data by default, regardless of if it's fetched by ID or as part of a findMany
. This means you can select any of the record's fields wherever you like in a GraphQL query according to the use case at hand.
Retrieving one Shopify Product Variant record
Individual Shopify Product Variant records can be retrieved using the "find by ID" API endpoint. You can also return only some fields, or
extra fields beyond what Gadget retrieves by default, using the select
option.
The findOne
function throws an error if no matching record is found, which you will need to catch and handle. Alternatively, you can use the maybeFindOne
function, which returns null
if no record is found, without throwing an error.
Similarly, the useFindOne
React hook returns (but does not throw) an error when no matching record is found, while the useMaybeFindOne
hook simply returns null
if no record is found, without also returning an error.
const shopifyProductVariantRecord = await api.shopifyProductVariant.findOne("some-id");console.log(shopifyProductVariantRecord.id); //=> a stringconsole.log(shopifyProductVariantRecord.createdAt); //=> a Date object
const [result, refresh] = useFindOne(api.shopifyProductVariant, "some-id");const { data, error, fetching } = result;console.log(data?.id); //=> a stringconsole.log(data?.createdAt); //=> a Date object
1query GetOneShopifyProductVariant($id: GadgetID!) {2 shopifyProductVariant(id: $id) {3 __typename4 id5 state6 barcode7 compareAtPrice8 createdAt9 fulfillmentService10 grams11 inventoryManagement12 inventoryPolicy13 inventoryQuantity14 inventoryQuantityAdjustment15 oldInventoryQuantity16 option117 option218 option319 position20 presentmentPrices21 price22 requiresShipping23 shopifyCreatedAt24 shopifyUpdatedAt25 sku26 taxCode27 taxable28 title29 updatedAt30 weight31 weightUnit32 }33}
{ "id": "some-id" }
Retrieving the first of many Shopify Product Variant records
The first record from a list of records can be retrieved using the "find first" API endpoint. The source list of records can be filtered using the filter
option, sorted using the sort
option, searched using the search
option, though no pagination options are available on this endpoint. You can also return only some fields, or extra fields beyond what Gadget retrieves by default using the select
option.
The findFirst
function throws an error if no matching record is found, which you will need to catch and handle. Alternatively, you can use the maybeFindFirst
function, which returns null
if no record is found, without throwing an error.
Similarly, the useFindFirst
React hook returns (but does not throw) an error when no matching record is found, while the useMaybeFindFirst
hook simply returns null
if no record is found, without also returning an error.
const shopifyProductVariantRecord = await api.shopifyProductVariant.findFirst();console.log(shopifyProductVariantRecord.id); //=> a stringconsole.log(shopifyProductVariantRecord.createdAt); //=> a Date object
const [result, refresh] = useFindFirst(api.shopifyProductVariant);const { data, error, fetching } = result;console.log(data?.id); //=> a stringconsole.log(data?.createdAt); //=> a Date object
1query FindManyShopifyProductVariants(2 $first: Int3 $search: String4 $sort: [ShopifyProductVariantSort!]5 $filter: [ShopifyProductVariantFilter!]6) {7 shopifyProductVariants(8 first: $first9 search: $search10 sort: $sort11 filter: $filter12 ) {13 edges {14 node {15 __typename16 id17 state18 barcode19 compareAtPrice20 createdAt21 fulfillmentService22 grams23 inventoryManagement24 inventoryPolicy25 inventoryQuantity26 inventoryQuantityAdjustment27 oldInventoryQuantity28 option129 option230 option331 position32 presentmentPrices33 price34 requiresShipping35 shopifyCreatedAt36 shopifyUpdatedAt37 sku38 taxCode39 taxable40 title41 updatedAt42 weight43 weightUnit44 }45 }46 }47}
{ "first": 1 }
Retrieving many Shopify Product Variant records
Pages of Shopify Product Variant records can be retrieved by using the "find many" API endpoint. The returned records can be filtered using the filter
option, sorted using the sort
option, searched using the search
option, and paginated using standard Relay-style pagination options. You can also return only some fields, or extra fields beyond what Gadget retrieves by default using the select
option.
This GraphQL endpoint returns records in the Relay Connection style (as a list of edge
s with node
s and cursor
s) so they can be paginated. The shopifyProductVariants
GraphQL endpoint works with any Relay-compatible caching client, or you can use Gadget's JS client for pagination with the findMany
function.
Find a page of Shopify Product Variants
Fetch a page of records with the shopifyProductVariant.findMany
JS method or the shopifyProductVariants
GraphQL field. No options are required. The records returned will be implicitly sorted by ID ascending.
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany();console.log(shopifyProductVariantRecords.length); //=> a numberconsole.log(shopifyProductVariantRecords[0].id); //=> a string
const [result, refresh] = useFindMany(api.shopifyProductVariant);const { data, error, fetching } = result;console.log(data?.length); //=> a numberconsole.log(data?.[0].length); //=> a string
1query FindManyShopifyProductVariants {2 shopifyProductVariants {3 edges {4 node {5 __typename6 id7 state8 # ...9 createdAt10 updatedAt11 }12 }13 }14}
{}
Sorting
Records can be sorted in the database to retrieve them in a certain order. Records are always implicitly sorted by ID ascending unless an explicit sort on the id
field is defined. The GraphQL type ShopifyProductVariantSort
defines which fields can be sorted by.
Records can be sorted by multiple different fields and in multiple different directions by passing a list of ShopifyProductVariantSort
instead of just one.
1input ShopifyProductVariantSort {2 id: SortOrder3 createdAt: SortOrder4 updatedAt: SortOrder5 state: SortOrder6 barcode: SortOrder7 compareAtPrice: SortOrder8 fulfillmentService: SortOrder9 grams: SortOrder10 inventoryManagement: SortOrder11 inventoryPolicy: SortOrder12 inventoryQuantity: SortOrder13 inventoryQuantityAdjustment: SortOrder14 oldInventoryQuantity: SortOrder15 option1: SortOrder16 option2: SortOrder17 option3: SortOrder18 position: SortOrder19 presentmentPrices: SortOrder20 price: SortOrder21 requiresShipping: SortOrder22 shopifyCreatedAt: SortOrder23 sku: SortOrder24 taxCode: SortOrder25 shopifyUpdatedAt: SortOrder26 taxable: SortOrder27 title: SortOrder28 weight: SortOrder29 weightUnit: SortOrder30}
Pass the sort
option to the JS client, or the sort
variable to a GraphQL query to sort the records returned.
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({sort: { createdAt: "Descending" },});
const [result, refresh] = useFindMany(api.shopifyProductVariant, {sort: { createdAt: "Descending" },});const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($sort: [ShopifyProductVariantSort!]) {2 shopifyProductVariants(sort: $sort) {3 edges {4 node {5 __typename6 id7 state8 # ...9 createdAt10 updatedAt11 }12 }13 }14}
{ "sort": { "createdAt": "Descending" } }
Sort by multiple fields by passing an array of { [field]: "Ascending" | "Descending" }
objects.
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({sort: [{ state: "Descending" }, { createdAt: "Ascending" }],});
const [result, refresh] = useFindMany(api.shopifyProductVariant, {sort: [{ state: "Descending" }, { createdAt: "Ascending" }],});const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($sort: [ShopifyProductVariantSort!]) {2 shopifyProductVariants(sort: $sort) {3 edges {4 node {5 __typename6 id7 state8 # ...9 createdAt10 updatedAt11 }12 }13 }14}
{ "sort": [{ "state": "Descending" }, { "createdAt": "Ascending" }] }
All primitive field types in Gadget are sortable so you are able to sort by fields you have added to a model as well.
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({sort: { id: "Descending" },});
const [result, refresh] = useFindMany(api.shopifyProductVariant, {sort: { id: "Descending" },});const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($sort: [ShopifyProductVariantSort!]) {2 shopifyProductVariants(sort: $sort) {3 edges {4 node {5 __typename6 id7 state8 # ...9 createdAt10 updatedAt11 }12 }13 }14}
{ "sort": { "id": "Descending" } }
Searching
Shopify Product Variant records can be searched using Gadget's built in full text search functionality. Gadget search is appropriate for powering
autocompletes, searchable tables, or other experiences where humans are writing search queries. It's typo tolerant, synonym aware and supports
simple search operators like !
to exclude search terms.
Search Shopify Product Variants by passing the search
parameter with a search query string.
Search isn't field specific in Gadget -- all String or RichText field types are searched with the built in search functionality.
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({search: "a specific phrase to search for",});
const [result, refresh] = useFindMany(api.shopifyProductVariant, {search: "a specific phrase to search for",});const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($search: String) {2 shopifyProductVariants(search: $search) {3 edges {4 node {5 __typename6 id7 state8 # ...9 createdAt10 updatedAt11 }12 }13 }14}
{ "search": "a specific phrase to search for" }
Filtering
Shopify Product Variant records can be filtered to return only the appropriate records. Records can be filtered on any field, including those managed by Gadget or fields added by developers. Filters can be combined with sorts, searches and paginated using cursor-based Relay pagination.
Filter Shopify Product Variants by passing the filter
parameter with a filter object. Filter objects are nestable boolean conditions expressed as JS objects capturing a key, an operator, and usually a value.
The GraphQL type ShopifyProductVariantFilter
defines which fields can be filtered on.
Records can be filtered by multiple different fields. If you want to combine filters using boolean logic, nest them under the AND
, OR
, or NOT
keys of a parent filter. Filters can be nested deeply by passing multiple levels boolean condition filters.
You can also pass a list of filters to the filter
parameter which will be implicitly AND
ed with one another such that they all need to match for a record to be returned.
1input ShopifyProductVariantFilter {2 AND: [ShopifyProductVariantFilter]3 OR: [ShopifyProductVariantFilter]4 NOT: [ShopifyProductVariantFilter]5 id: IDFilter6 createdAt: DateTimeFilter7 updatedAt: DateTimeFilter8 state: StateFilter9 barcode: StringFilter10 compareAtPrice: StringFilter11 fulfillmentService: StringFilter12 grams: FloatFilter13 inventoryManagement: StringFilter14 inventoryPolicy: StringFilter15 productImage: IDFilter16 inventoryQuantity: FloatFilter17 inventoryQuantityAdjustment: FloatFilter18 oldInventoryQuantity: FloatFilter19 option1: StringFilter20 option2: StringFilter21 option3: StringFilter22 position: FloatFilter23 presentmentPrices: JSONFilter24 price: StringFilter25 requiresShipping: BooleanFilter26 product: IDFilter27 shopifyCreatedAt: DateTimeFilter28 sku: StringFilter29 taxCode: StringFilter30 shopifyUpdatedAt: DateTimeFilter31 taxable: BooleanFilter32 title: StringFilter33 weight: FloatFilter34 weightUnit: StringFilter35 shop: IDFilter36}
const yesterday = new Date(Date.now() - 864e5);const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({filter: { createdAt: { greaterThan: yesterday } },});
const yesterday = new Date(Date.now() - 864e5);const [result, refresh] = useFindMany(api.shopifyProductVariant, {filter: { createdAt: { greaterThan: yesterday } },});const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($filter: [ShopifyProductVariantFilter!]) {2 shopifyProductVariants(filter: $filter) {3 edges {4 node {5 __typename6 id7 state8 # ...9 createdAt10 updatedAt11 }12 }13 }14}
{ "filter": { "createdAt": { "greaterThan": "2023-01-31T13:13:54.769Z" } } }
1const yesterday = new Date(Date.now() - 86400000);2const oneWeekAgo = new Date(Date.now() - 604800000);3const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({4 filter: {5 OR: [6 {7 createdAt: { greaterThan: oneWeekAgo },8 },9 {10 updated: { greaterThan: yesterday },11 },12 ],13 },14});
1const yesterday = new Date(Date.now() - 86400000);2const oneWeekAgo = new Date(Date.now() - 604800000);3const [result, refresh] = useFindMany(api.shopifyProductVariant, {4 filter: {5 OR: [6 {7 createdAt: { greaterThan: oneWeekAgo },8 },9 {10 updated: { greaterThan: yesterday },11 },12 ],13 },14});15const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($filter: [ShopifyProductVariantFilter!]) {2 shopifyProductVariants(filter: $filter) {3 edges {4 node {5 __typename6 id7 state8 # ...9 createdAt10 updatedAt11 }12 }13 }14}
1{2 "filter": {3 "OR": [4 { "createdAt": { "greaterThan": "2023-01-25T13:13:54.769Z" } },5 { "updated": { "greaterThan": "2023-01-31T13:13:54.769Z" } }6 ]7 }8}
Filter records that are in the created state
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({filter: {state: { inState: "created" },},});
1const [result, refresh] = useFindMany(api.shopifyProductVariant, {2 filter: {3 state: { inState: "created" },4 },5});6const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($filter: [ShopifyProductVariantFilter!]) {2 shopifyProductVariants(filter: $filter) {3 edges {4 node {5 __typename6 id7 state8 # ...9 createdAt10 updatedAt11 }12 }13 }14}
{ "filter": { "state": { "inState": "created" } } }
Most field types in Gadget are filterable, so you are able to filter by fields you have added to a model as well.
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({filter: {id: { isSet: true },},});
1const [result, refresh] = useFindMany(api.shopifyProductVariant, {2 filter: {3 id: { isSet: true },4 },5});6const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($filter: [ShopifyProductVariantFilter!]) {2 shopifyProductVariants(filter: $filter) {3 edges {4 node {5 __typename6 id7 state8 # ...9 createdAt10 updatedAt11 }12 }13 }14}
{ "filter": { "id": { "isSet": true } } }
Pagination
All Gadget record lists, including the top level Shopify Product Variant finder as well as associations to Shopify Product Variant, are structured as GraphQL connections. GraphQL connections are the de facto standard for querying lists and support cursor-based forward and backward pagination. When querying via GraphQL, you must select the edges
field and then the node
field to get the Shopify Product Variant record. When querying using a Gadget API client, the GraphQL queries are generated for you and the records are unwrapped and returned as a GadgetRecordList
ready for use.
Shopify Product Variant pagination supports the standard GraphQL connection pagination arguments: first
+ after
, or last
+ before
. Pagination
is done using cursors, which you can retrieve from the edge.cursor
field or the pageInfo.startCursor
properties.
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({first: 25,});console.log(shopifyProductVariantRecords.length); //=> no greater than 25
const [result, refresh] = useFindMany(api.shopifyProductVariant, { first: 25 });const { data, error, fetching } = result;console.log(data?.length); //=> no greater than 25
1query FindManyShopifyProductVariants($first: Int, $after: String) {2 shopifyProductVariants(first: $first, after: $after) {3 edges {4 cursor5 node {6 __typename7 id8 state9 # ...10 createdAt11 updatedAt12 }13 }14 pageInfo {15 endCursor16 hasNextPage17 hasPreviousPage18 startCursor19 }20 }21}
{ "first": 25 }
The after
cursor used in this example data won't return any records if used in a real API request.
const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({after: "abcdefg",first: 25,});
const [result, refresh] = useFindMany(api.shopifyProductVariant, {after: "abcdefg",first: 25,});const { data, error, fetching } = result;
1query FindManyShopifyProductVariants($first: Int, $after: String) {2 shopifyProductVariants(first: $first, after: $after) {3 edges {4 cursor5 node {6 __typename7 id8 state9 # ...10 createdAt11 updatedAt12 }13 }14 pageInfo {15 endCursor16 hasNextPage17 hasPreviousPage18 startCursor19 }20 }21}
{ "first": 25, "after": "abcdefg" }
Pagination Limits
Root-level record finders like shopifyProductVariants
support a maximum page size of 250 records and a default page size of 50 records. The page size is controlled using the first
or last
GraphQL field arguments.
Related record finders that access lists of records through a has many or has many field support a maximum page size of 100 records and a default page size of 50 records.
Get the next or previous page
When using the generated JavaScript API client, including the api
parameter in a Gadget code effect, the record lists returned from findMany calls can be paginated using the nextPage()
or previousPage()
option.
Both nextPage()
and previousPage()
will throw an error if the corresponding hasNextPage
or hasPreviousPage
is false
.
1const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany();2if (shopifyProductVariantRecords.hasNextPage) {3 const nextPage = await shopifyProductVariantRecords.nextPage();4}5if (shopifyProductVariantRecords.hasPreviousPage) {6 const prevPage = await shopifyProductVariantRecords.previousPage();7}
When using React and paging through records, you can use cursors to get the previous or next pages of records. This is an example of a React component that pages forward and backward through 2 records at a time for props.model.name.
1import { api } from "../api"; // your Gadget project's API Client2import { useFindMany } from "@gadgetinc/react";3import { useCallback, useState } from "react";45export default function TestComponent() {6 const NUM_ON_PAGE = 2; // the number of records per page78 const [cursor, setCursor] = useState({ first: NUM_ON_PAGE });9 // using Gadget React hooks to fetch records of shopifyProductVariant10 const [{ data, fetching, error }] = useFindMany(api.shopifyProductVariant, {11 ...cursor,12 });1314 const getNextPage = useCallback(() => {15 // use first + after to page forwards16 setCursor({ first: NUM_ON_PAGE, after: data.endCursor });17 }, [data]);1819 const getPreviousPage = useCallback(() => {20 // use last + before to page backwards21 setCursor({ last: NUM_ON_PAGE, before: data.startCursor });22 }, [data]);2324 return (25 <div>26 <button onClick={getPreviousPage} disabled={!data?.hasPreviousPage}>27 Previous page28 </button>29 <button onClick={getNextPage} disabled={!data?.hasNextPage}>30 Next page31 </button>32 {!fetching && data.map((d) => <div>{d.id}</div>)}33 </div>34 );35}
Get all records
If you need to get all available data for Shopify Product Variant, you will need to paginate through all pages of data. If you have a large amount of data, this can take a long time. Make sure you need to collect all data at once before writing a pagination loop that reads all records! If you are querying records for display in a UI and cannot display all your records at once, we don't recommend fetching all the data beforehand - instead, use the cursor to read additional data when the user needs it.
If you need all data for analytics applications or to collect some statistics on your data, consider options like intermediate models and pre-defined data rollups.
If you have determined that you need all your data, you can fetch it using cursors and a loop. We also suggest using select
so that you only grab fields that are needed, in addition to applying a filter
, if possible. Using first
with the maximum allowable value will also allow you to grab the maximum number of records you can at once.
1const allRecords = []; // use allRecords to store all records2let records = await api.shopifyProductVariant.findMany({3 first: 250,4 select: {5 id: true,6 },7 filter: {8 // add filter conditions, if possible9 },10});1112allRecords.push(...records);1314// loop through additional pages to get all protected orders15while (records.hasNextPage) {16 // paginate17 records = await records.nextPage();18 allRecords.push(...records);19}
Selecting fields, and fields of fields
When using the JavaScript client, all of findOne
, maybeFindOne
, findMany
, findFirst
, maybeFindFirst
, and various action functions, allow requesting specific fields of a Shopify Product Variant and its relationships. The select
option controls which fields are selected in the generated GraphQL query sent to the Gadget API. Pass each field you want to select in an object, with true
as the value for scalar fields, and a nested object of the same shape for nested fields.
Gadget has a default selection that will retrieve all of the scalar fields for a Shopify Product Variant. If you don't pass a select
option to a record finder, this default selection will be used.
1// fetch only the id, state, and createdAt field2const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({3 select: { id: true, state: true, createdAt: true },4});5// fetch all the scalar fields for the model, but no relationship fields6const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany();
1// fetch only the id, state, and createdAt field2const [result, refresh] = useFindMany(api.shopifyProductVariant, {3 select: { id: true, state: true, createdAt: true },4});5const { data, error, fetching } = result;6// fetch all the scalar fields for the model, but no relationship fields7const [result, refresh] = useFindMany(api.shopifyProductVariant);8const { data, error, fetching } = result;
Type Safety
The select
option is fully type safe if you're using TypeScript. The returned GadgetRecord
type will have a <Shape>
exactly matching the fields and nested fields you selected. For more information, see Type Safety
.
This behavior of selecting only some fields is built right into GraphQL. If you want to limit or expand what you retrieve from a GraphQL query, include or exclude those fields in your GraphQL query. For more information on executing GraphQL queries, see GraphQL.
1// fetch the id, state, and createdAt field, and fetch some nested fields from an example relationship field named `someRelatedObject`2const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({3 select: {4 id: true,5 state: true,6 createdAt: true,7 someRelatedObject: { id: true, createdAt: true },8 },9});
1// fetch the id, state, and createdAt field, and fetch some nested fields from an example relationship field named `someRelatedObject`2const [result, refresh] = useFindMany(api.shopifyProductVariant, {3 select: {4 id: true,5 state: true,6 createdAt: true,7 someRelatedObject: { id: true, createdAt: true },8 },9});10const { data, error, fetching } = result;
Combining parameters
Sort, search, filtering, selection, and pagination parameters can be combined to access the exact set of records needed for your use case.
1const shopifyProductVariantRecords = await api.shopifyProductVariant.findMany({2 search: "<some search query>",3 sort: { createdAt: "Descending" },4 filter: { updatedAt: { greaterThan: new Date(Date.now() - 864e5) } },5 select: { id: true, createdAt: true },6 first: 25,7 after: "abcdefg",8});
1const [result, refresh] = useFindMany(api.shopifyProductVariant, {2 search: "<some search query>",3 sort: { createdAt: "Descending" },4 filter: { updatedAt: { greaterThan: new Date(Date.now() - 864e5) } },5 select: { id: true, createdAt: true },6 first: 25,7 after: "abcdefg",8});9const { data, error, fetching } = result;
1query FindManyShopifyProductVariants(2 $after: String3 $before: String4 $first: Int5 $last: Int6 $search: String7 $sort: [ShopifyProductVariantSort!]8 $filter: [ShopifyProductVariantFilter!]9) {10 shopifyProductVariants(11 after: $after12 before: $before13 first: $first14 last: $last15 search: $search16 sort: $sort17 filter: $filter18 ) {19 edges {20 cursor21 node {22 __typename23 id24 state25 barcode26 compareAtPrice27 createdAt28 fulfillmentService29 grams30 inventoryManagement31 inventoryPolicy32 inventoryQuantity33 inventoryQuantityAdjustment34 oldInventoryQuantity35 option136 option237 option338 position39 presentmentPrices40 price41 requiresShipping42 shopifyCreatedAt43 shopifyUpdatedAt44 sku45 taxCode46 taxable47 title48 updatedAt49 weight50 weightUnit51 }52 }53 pageInfo {54 endCursor55 hasNextPage56 hasPreviousPage57 startCursor58 }59 }60}
1{2 "search": "<some search query>",3 "sort": { "createdAt": "Descending" },4 "filter": { "updatedAt": { "greaterThan": "2023-01-31T13:13:54.956Z" } },5 "first": 25,6 "after": "abcdefg"7}
Invoking Actions
Shopify Product Variant records are changed by invoking Actions. Actions are the things that "do" stuff -- update records, make API calls, call backend code, etc. Actions each have one corresponding GraphQL mutation and a corresponding function available in the API client libraries. Nested Actions can also be invoked with the API client, by providing the actions as input to any relationship fields.
Action Result format
Each API action returns results in the same format that includes a success indicator, errors, and the actual result if the action succeeded. The result is the record that was acted on for a model action, or a list of records for a bulk action, or a JSON blob for Global Actions. Model actions that delete the record don't return the record.
The success
field returns a boolean indicating if the action executed as expected. Any execution errors are returned in the errors
object, which will always be null
if success
is true or contain ExecutionError
objects if success
is false.
ExecutionError
objects always have a message
describing what error prevented the action from succeeding, as well as a code
attribute that gives a stable, searchable, human readable error class code for referencing this specific error. Details on each error code can be found in the Errors documentation. All ExecutionError
object types returned by the GraphQL object can be one of many types of error, where some types have extra data that is useful for remedying the error. All error types will always have message
and code
properties, but some, like InvalidRecordError
have extra fields for use by clients.
Errors when using the generated client
The generated JavaScript client automatically interprets errors from invoking actions and throws JavaScript Error
instances if the action didn't succeed. The Error
objects it throws are rich, and expose extra error properties beyond just message
and code
if they exist.
Errors thrown by the JavaScript client are easiest to catch by using a try/catch
statement around an await
, like so:
1import {2 GadgetOperationError,3 InvalidRecordError,4} from "@gadget-client/example-app";56// must be in an async function to use `await` syntax7const runAction = async () => {8 try {9 return await api.exampleModel.create({10 exampleModel: { name: "example record name" },11 });12 } catch (error) {13 if (error instanceof GadgetOperationError) {14 // a recognized general error has occurred, retry the operation or inspect error.code`15 console.error(error);16 } else if (error instanceof InvalidRecordError) {17 // the submitted input data for the action was invalid, inspect the invalid fields which `InvalidRecordError` exposes18 console.error(error.validationErrors);19 } else {20 // an unrecognized error occurred, like an HTTP connection interrupted error or a syntax error. Re-throw it because it's not clear what to do to fix ti21 throw error;22 }23 }24};
For more information on error codes, consult the Errors documentation.
Shopify Product Variant create
Input
create
accepts the following input parameters:
1export interface CreateShopifyProductVariantInput {2 id?: (Scalars["GadgetID"] | null) | null;34 barcode?: (Scalars["String"] | null) | null;56 compareAtPrice?: (Scalars["String"] | null) | null;78 fulfillmentService?: (Scalars["String"] | null) | null;910 grams?: (Scalars["Float"] | null) | null;1112 inventoryManagement?: (Scalars["String"] | null) | null;1314 inventoryPolicy?: (Scalars["String"] | null) | null;1516 productImage?: ShopifyProductImageBelongsToInput | null;1718 inventoryQuantity?: (Scalars["Float"] | null) | null;1920 inventoryQuantityAdjustment?: (Scalars["Float"] | null) | null;2122 oldInventoryQuantity?: (Scalars["Float"] | null) | null;2324 option1?: (Scalars["String"] | null) | null;2526 option2?: (Scalars["String"] | null) | null;2728 option3?: (Scalars["String"] | null) | null;2930 position?: (Scalars["Float"] | null) | null;3132 presentmentPrices?: (Scalars["JSON"] | null) | null;3334 price?: (Scalars["String"] | null) | null;3536 requiresShipping?: (Scalars["Boolean"] | null) | null;3738 product?: ShopifyProductBelongsToInput | null;3940 shopifyCreatedAt?: Date | Scalars["ISO8601DateString"] | null;4142 sku?: (Scalars["String"] | null) | null;4344 taxCode?: (Scalars["String"] | null) | null;4546 shopifyUpdatedAt?: Date | Scalars["ISO8601DateString"] | null;4748 taxable?: (Scalars["Boolean"] | null) | null;4950 title?: (Scalars["String"] | null) | null;5152 weight?: (Scalars["Float"] | null) | null;5354 weightUnit?: (Scalars["String"] | null) | null;5556 shop?: ShopifyShopBelongsToInput | null;5758 results?: (ResultHasManyInput | null)[];59}6061export interface CreateShopifyProductVariantArguments {62 shopifyProductVariant?: CreateShopifyProductVariantInput | null;63}
1input CreateShopifyProductVariantInput {2 id: GadgetID3 barcode: String4 compareAtPrice: String5 fulfillmentService: String6 grams: Float7 inventoryManagement: String8 inventoryPolicy: String9 productImage: ShopifyProductImageBelongsToInput10 inventoryQuantity: Float11 inventoryQuantityAdjustment: Float12 oldInventoryQuantity: Float13 option1: String14 option2: String15 option3: String16 position: Float17 presentmentPrices: JSON18 price: String19 requiresShipping: Boolean20 product: ShopifyProductBelongsToInput21 shopifyCreatedAt: DateTime22 sku: String23 taxCode: String24 shopifyUpdatedAt: DateTime25 taxable: Boolean26 title: String27 weight: Float28 weightUnit: String29 shop: ShopifyShopBelongsToInput30 results: [ResultHasManyInput]31}3233input CreateShopifyProductVariantArguments {34 shopifyProductVariant: CreateShopifyProductVariantInput35}
1const shopifyProductVariantRecord = await api.shopifyProductVariant.create({2 shopifyProductVariant: {3 // field values for Shopify Product Variant4 },5});6console.log(shopifyProductVariantRecord.id); //=> a string
1const [result, createShopifyProductVariant] = useAction(2 api.shopifyProductVariant.create3);4const { data, error, fetching } = result;5await createShopifyProductVariant({6 shopifyProductVariant: {7 // field values for Shopify Product Variant8 },9});10console.log(data?.id); //=> a string
1mutation ($shopifyProductVariant: CreateShopifyProductVariantInput) {2 createShopifyProductVariant(shopifyProductVariant: $shopifyProductVariant) {3 success4 errors {5 message6 ... on InvalidRecordError {7 validationErrors {8 apiIdentifier9 message10 }11 record12 model {13 apiIdentifier14 }15 }16 }17 shopifyProductVariant {18 __typename19 id20 state21 barcode22 compareAtPrice23 createdAt24 fulfillmentService25 grams26 inventoryManagement27 inventoryPolicy28 inventoryQuantity29 inventoryQuantityAdjustment30 oldInventoryQuantity31 option132 option233 option334 position35 presentmentPrices36 price37 requiresShipping38 shopifyCreatedAt39 shopifyUpdatedAt40 sku41 taxCode42 taxable43 title44 updatedAt45 weight46 weightUnit47 }48 }49}
{ "shopifyProductVariant": {} }
Output
create
returns the Shopify Product Variant. In the JS client, the fields returned can be controlled with the select
option. In GraphQL, the return format is the action result format, which includes the record if the action was successful. You can include or exclude the fields you need right in the mutation itself.
type CreateShopifyProductVariantResult {success: Boolean!errors: [ExecutionError!]shopifyProductVariant: ShopifyProductVariant}
Shopify Product Variant update
Input
update
operates on one Shopify Product Variant in particular, identified by the id
variable.update
accepts the following input parameters:
1export interface UpdateShopifyProductVariantInput {2 id?: (Scalars["GadgetID"] | null) | null;34 barcode?: (Scalars["String"] | null) | null;56 compareAtPrice?: (Scalars["String"] | null) | null;78 fulfillmentService?: (Scalars["String"] | null) | null;910 grams?: (Scalars["Float"] | null) | null;1112 inventoryManagement?: (Scalars["String"] | null) | null;1314 inventoryPolicy?: (Scalars["String"] | null) | null;1516 productImage?: ShopifyProductImageBelongsToInput | null;1718 inventoryQuantity?: (Scalars["Float"] | null) | null;1920 inventoryQuantityAdjustment?: (Scalars["Float"] | null) | null;2122 oldInventoryQuantity?: (Scalars["Float"] | null) | null;2324 option1?: (Scalars["String"] | null) | null;2526 option2?: (Scalars["String"] | null) | null;2728 option3?: (Scalars["String"] | null) | null;2930 position?: (Scalars["Float"] | null) | null;3132 presentmentPrices?: (Scalars["JSON"] | null) | null;3334 price?: (Scalars["String"] | null) | null;3536 requiresShipping?: (Scalars["Boolean"] | null) | null;3738 product?: ShopifyProductBelongsToInput | null;3940 shopifyCreatedAt?: Date | Scalars["ISO8601DateString"] | null;4142 sku?: (Scalars["String"] | null) | null;4344 taxCode?: (Scalars["String"] | null) | null;4546 shopifyUpdatedAt?: Date | Scalars["ISO8601DateString"] | null;4748 taxable?: (Scalars["Boolean"] | null) | null;4950 title?: (Scalars["String"] | null) | null;5152 weight?: (Scalars["Float"] | null) | null;5354 weightUnit?: (Scalars["String"] | null) | null;5556 shop?: ShopifyShopBelongsToInput | null;5758 results?: (ResultHasManyInput | null)[];59}6061export interface UpdateShopifyProductVariantArguments {62 shopifyProductVariant?: UpdateShopifyProductVariantInput | null;63}
1input UpdateShopifyProductVariantInput {2 id: GadgetID3 barcode: String4 compareAtPrice: String5 fulfillmentService: String6 grams: Float7 inventoryManagement: String8 inventoryPolicy: String9 productImage: ShopifyProductImageBelongsToInput10 inventoryQuantity: Float11 inventoryQuantityAdjustment: Float12 oldInventoryQuantity: Float13 option1: String14 option2: String15 option3: String16 position: Float17 presentmentPrices: JSON18 price: String19 requiresShipping: Boolean20 product: ShopifyProductBelongsToInput21 shopifyCreatedAt: DateTime22 sku: String23 taxCode: String24 shopifyUpdatedAt: DateTime25 taxable: Boolean26 title: String27 weight: Float28 weightUnit: String29 shop: ShopifyShopBelongsToInput30 results: [ResultHasManyInput]31}3233input UpdateShopifyProductVariantArguments {34 shopifyProductVariant: UpdateShopifyProductVariantInput35}
1const shopifyProductVariantRecord = await api.shopifyProductVariant.update(2 "some-id",3 {4 shopifyProductVariant: {5 // field values for Shopify Product Variant6 },7 }8);9console.log(shopifyProductVariantRecord.id); //=> a string
1const [result, updateShopifyProductVariant] = useAction(2 api.shopifyProductVariant.update3);4const { data, error, fetching } = result;5await updateShopifyProductVariant({6 id: "some-id",7 shopifyProductVariant: {8 // field values for Shopify Product Variant9 },10});11console.log(data?.id); //=> a string
1mutation ($id: GadgetID!, $shopifyProductVariant: UpdateShopifyProductVariantInput) {2 updateShopifyProductVariant(3 id: $id4 shopifyProductVariant: $shopifyProductVariant5 ) {6 success7 errors {8 message9 ... on InvalidRecordError {10 validationErrors {11 apiIdentifier12 message13 }14 record15 model {16 apiIdentifier17 }18 }19 }20 shopifyProductVariant {21 __typename22 id23 state24 barcode25 compareAtPrice26 createdAt27 fulfillmentService28 grams29 inventoryManagement30 inventoryPolicy31 inventoryQuantity32 inventoryQuantityAdjustment33 oldInventoryQuantity34 option135 option236 option337 position38 presentmentPrices39 price40 requiresShipping41 shopifyCreatedAt42 shopifyUpdatedAt43 sku44 taxCode45 taxable46 title47 updatedAt48 weight49 weightUnit50 }51 }52}
{ "id": "some-id", "shopifyProductVariant": {} }
Output
update
returns the Shopify Product Variant. In the JS client, the fields returned can be controlled with the select
option. In GraphQL, the return format is the action result format, which includes the record if the action was successful. You can include or exclude the fields you need right in the mutation itself.
type UpdateShopifyProductVariantResult {success: Boolean!errors: [ExecutionError!]shopifyProductVariant: ShopifyProductVariant}
Shopify Product Variant delete
The delete
action destroys the record.
Input
delete
operates on one Shopify Product Variant in particular, identified by the id
variable.
await api.shopifyProductVariant.delete("some-id");
1const [result, deleteShopifyProductVariant] = useAction(2 api.shopifyProductVariant.delete3);4const { data, error, fetching } = result;5await deleteShopifyProductVariant({6 id: "some-id",7});
1mutation ($id: GadgetID!) {2 deleteShopifyProductVariant(id: $id) {3 success4 errors {5 message6 ... on InvalidRecordError {7 validationErrors {8 apiIdentifier9 message10 }11 record12 model {13 apiIdentifier14 }15 }16 }17 }18}
{ "id": "some-id" }
Output
delete
deletes the record, so it returns void
in the JS client. In GraphQL it returns only the success
and errors
from the action result format.
type DeleteShopifyProductVariantResult {success: Boolean!errors: [ExecutionError!]}
Linking Related Records
Linking to an Existing Child Record
During a create
or update
operation, you can link to existing child records simply by nesting the data structure on your operation, using an update
object wrapper around the child record's properties.
1const shopifyProductImageRecord = await api.shopifyProductImage.create({2 shopifyProductImage: {3 height: "heightValue",4 variants: {5 // Updates existing `shopifyProductVariant` record6 // (`id` of record required),7 // and links it to shopifyProductImage.8 update: {9 id: "123",10 barcode: "variantsBarcodeValue",11 },12 },13 },14});15console.log(shopifyProductImageRecord.id); //=> a string
1const [result, createShopifyProductImage] = useAction(2 api.shopifyProductImage.create3);4const { data, error, fetching } = result;5await createShopifyProductImage({6 shopifyProductImage: {7 height: "heightValue",8 variants: {9 // Updates existing `shopifyProductVariant` record10 // (`id` of record required),11 // and links it to shopifyProductImage.12 update: {13 id: "123",14 barcode: "variantsBarcodeValue",15 },16 },17 },18});19console.log(data?.id); //=> a string
1mutation ($shopifyProductImage: CreateShopifyProductImageInput) {2 createShopifyProductImage(shopifyProductImage: $shopifyProductImage) {3 success4 errors {5 message6 }7 shopifyProductImage {8 id9 height10 variants {11 id12 }13 }14 }15}
{"height": "heightValue","variants": { "update": { "id": "123", "barcode": "variantsBarcodeValue" } }}
Linking to a New Child Record
During a create
or update
operation, you can create linked child records simply by nesting the data structure on your operation, using a create
object wrapper around the child record's properties.
1const shopifyProductImageRecord = await api.shopifyProductImage.create({2 shopifyProductImage: {3 height: "heightValue",4 variants: {5 // Creates `shopifyProductVariant` record,6 // linked to shopifyProductImage.7 create: {8 barcode: "variantsBarcodeValue",9 },10 },11 },12});13console.log(shopifyProductImageRecord.id); //=> a string
1const [result, createShopifyProductImage] = useAction(2 api.shopifyProductImage.create3);4const { data, error, fetching } = result;5await createShopifyProductImage({6 shopifyProductImage: {7 height: "heightValue",8 variants: {9 // Creates `shopifyProductVariant` record,10 // linked to shopifyProductImage.11 create: {12 barcode: "variantsBarcodeValue",13 },14 },15 },16});17console.log(data?.id); //=> a string
1mutation ($shopifyProductImage: CreateShopifyProductImageInput) {2 createShopifyProductImage(shopifyProductImage: $shopifyProductImage) {3 success4 errors {5 message6 }7 shopifyProductImage {8 id9 height10 variants {11 id12 }13 }14 }15}
{"height": "heightValue","variants": { "create": { "barcode": "variantsBarcodeValue" } }}
Linking to an Existing Parent Record
When you wish to link to an existing parent record, you must use a _link
property in your data, with the id
of the parent record that this child record will belong to.
1const shopifyProductVariantRecord = await api.shopifyProductVariant.create({2 shopifyProductVariant: {3 barcode: "barcodeValue",4 productImage: {5 _link: "123",6 },7 },8});9console.log(shopifyProductVariantRecord.id); //=> a string
1const [result, createShopifyProductVariant] = useAction(2 api.shopifyProductVariant.create3);4const { data, error, fetching } = result;5await createShopifyProductVariant({6 shopifyProductVariant: {7 barcode: "barcodeValue",8 productImage: {9 _link: "123",10 },11 },12});13console.log(data?.id); //=> a string
1mutation ($shopifyProductVariant: CreateShopifyProductVariantInput) {2 createShopifyProductVariant(shopifyProductVariant: $shopifyProductVariant) {3 success4 errors {5 message6 }7 shopifyProductVariant {8 id9 barcode10 productImage {11 id12 }13 }14 }15}
{ "barcode": "barcodeValue", "productImage": { "_link": "123" } }
Linking to a New Parent Record
You cannot directly link to a new parent record when creation a child record. However, you can jointly create both parent and child via the Linking to a New Child Record method.
Bulk Actions
Actions that support it can be performed in bulk. Bulk Actions are executed as a single GraphQL mutation and have a corresponding function available in the API client libraries.
Bulk Actions are performed on a set of ids
. Bulk Actions repeat the same action, with the same options and parameters, across all ids
and should not be confused with batching
up different actions in the same request.
Bulk Actions will be performed on the entire set. If an action fails on an individual record, the Bulk Action will still occur on the other records in the set. Only the records which completed the action successfully will be returned.
Bulk Shopify Product Variant delete
bulkDeleteShopifyProductVariants
action destroys the records.
Input
bulkDeleteShopifyProductVariants
operates on a set of Shopify Product Variants, identified by the ids
variable.
await api.shopifyProductVariant.bulkDelete(["some-id", "another-id"]);
const [shopifyProductVariantResult, bulkDelete] = useBulkAction(api.shopifyProductVariant.bulkDelete);const { data, error, fetching } = result;await bulkDelete({ ids: ["some-id", "another-id"] });
1mutation ($ids: [GadgetID!]!) {2 bulkDeleteShopifyProductVariants(ids: $ids) {3 success4 errors {5 message6 }7 }8}
{ "ids": ["some-id", "another-id"] }
Output
bulkDeleteShopifyProductVariants
deletes the record, so it returns void
in the JS client. In GraphQL it returns only the success
and errors
from the action result format.
type BulkDeleteShopifyProductVariantsResult {success: Boolean!errors: [ExecutionError!]}