Hi Team,
Can someone please explain me the logic of the CIF component: /apps/core/cif/components/commerce/product/v3/product
Foe testing purpose, I have deleted all the content from /apps/core/cif/components/commerce/product/v3/product/productFullDetail.html
Stil, in the logs I can see:
com.adobe.cq.commerce.core.components.client.MagentoGraphqlClient Cache hit for query
'{products(filter:{url_key:{eq:"carina-cardigan"}}){items{__typename,sku,url_key,name,description{html},image{label,url},thumbnail{l ....
That means, even if we are not rendering anything from Sightly component, still backend logic calls the GraphQL query to get the data.
Ofcourse, Sling model is called from: /apps/core/cif/components/commerce/product/v3/product/product.html
Can someone tell where exactly the logic is written to the GraphQL response:
I can see com.adobe.cq.commerce.core.components.models.retriever.AbstractProductRetriever
Here, method:
@Override
protected void populate() {
// Get product list from response
GraphqlResponse<Query, Error> response = executeQuery();
errors = response.getErrors();
if (CollectionUtils.isEmpty(errors)) {
Query rootQuery = response.getData();
List<ProductInterface> products = rootQuery.getProducts().getItems();
// Return first product in list unless the identifier type is 'url_key',
// then return the product whose 'url_key' matches the identifier
if (products.size() > 0) {
product = Optional.of(products.get(0));
} else {
product = Optional.empty();
}
} else {
product = Optional.empty();
}
}
Is this, the logic to get the particular product details. If yes, which method calls this. I was traversing through : com.adobe.cq.commerce.core.components.internal.models.v3.product.ProductImpl and then its super classes to crack the logic. Still, I am bit confused here.
Can someone help to crack the logic of this component.
cc: @Hemalatha @AMANATH_ULLAH @MukeshYadav_
Thanks in advance.
Solved! Go to Solution.
Views
Replies
Total Likes
Hi @Mahesh_Gunaje
Firstly
private GraphqlResponse<Query, Error> executeCached(String query, RequestOptions options) {
try {
if (localResponseCache != null && localResponseCache.containsKey(query)) {
return localResponseCache.get(query);
}
GraphqlRequest request = new GraphqlRequest(query);
GraphqlResponse<Query, Error> response = graphqlClient.execute(request, Query.class, Error.class, options);
if (localResponseCache != null) {
localResponseCache.put(query, response);
}
return response;
} catch (RuntimeException ex) {
LOGGER.error("Failed to execute query: {}", query, ex);
return newErrorResponse(ex);
}
}
Let me know if this was your query.
Hi @Mahesh_Gunaje
You are correct,
Inside com.adobe.cq.commerce.core.components.models.retriever.AbstractProductRetriever
The populate() method is used to fetch product info using graphql query.
The flow is ::
All the getter methods of
public ProductInterface fetchProduct() {
if (this.product == null) {
populate();
}
return this.product.orElse(null);
}
We have the logic to call populate() method, if the product is not already fetched using graphql query.
Let me know if you are looking for anything else or a solution around this.
1:So, if we call fetchProduct() method multiple times, still graphQL query will be called only once. Correct me if I am wrong.
2: Whats is the type of product object. Since, ProductInterface is an interface only. is product is object of ConfigurableProduct class?
One more observation from my side @pulkitvashisth
com.adobe.cq.commerce.core.components.internal.models.v3.product.ProductImpl.java file
@PostConstruct
protected void initModel()
init method is callled several times if I load the page: http://localhost:4502/content/venia/us/en/products/product-page.html/venia-tops/venia-sweaters/carin...
I mean more than 10 times. Is this the normal behavior? I mean calling init method multiple times is the normal one?
Wanted to check, is there any personal blogs, Adobe articles related to implementation of AEM CIF framework?
Thanks in advance.
One more query.
Which method calls the method: populate of AbstractProductRetriever.java for the first time, during the page load:
http://localhost:4502/content/venia/us/en/products/product-page.html/venia-tops/venia-sweaters/carin...
In debug mode, I came to know that Sling filter: com.adobe.cq.commerce.core.components.internal.servlets.CatalogPageNotFoundFilter.java
calls populate method as mentioned below:
if (siteStructure.isProductPage(currentPage)) {
removeSlingScriptHelperFromBindings = addSlingScriptHelperIfNeeded(slingRequest, slingResponse);
Product product = commerceModelFinder.findProductComponentModel(slingRequest, currentPage.getContentResource());
if (product != null && !product.getFound()) {
slingResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "Product not found");
return;
}
}
But according to me, at the end of init method of com.adobe.cq.commerce.core.components.internal.models.v3.product.java
populate() method has to be called. Since, in this initModel method calls: super.initModel();
Then, this method sets the productRetriever.extendProductQueryWith.
So, I am bit consfused with: for the first time, during the page load(above mentioned URL), which method calls the populate method?
Hi @Mahesh_Gunaje
Firstly
private GraphqlResponse<Query, Error> executeCached(String query, RequestOptions options) {
try {
if (localResponseCache != null && localResponseCache.containsKey(query)) {
return localResponseCache.get(query);
}
GraphqlRequest request = new GraphqlRequest(query);
GraphqlResponse<Query, Error> response = graphqlClient.execute(request, Query.class, Error.class, options);
if (localResponseCache != null) {
localResponseCache.put(query, response);
}
return response;
} catch (RuntimeException ex) {
LOGGER.error("Failed to execute query: {}", query, ex);
return newErrorResponse(ex);
}
}
Let me know if this was your query.
Views
Likes
Replies
Views
Likes
Replies