Why does this always show `PDP` and never `Cart` e...
# suitecommerce
k
Why does this always show
PDP
and never
Cart
even when I am in the Cart?
Copy code
var PDP = container.getComponent('PDP');
        var Cart = container.getComponent('Cart');
        
        if (PDP) {
          console.log("PDP Component");
        }
        else if (Cart) {
          console.log("Cart Component");
        }
After this conditional works... I want to iterate over the lines in the cart, compare the quantity in cart to the quantity available and display a Stock Info Message. How would one do that?
s
Because
if (PDP)
only checks for the existence of the PDP component, not whether you on a product detail page specifically
k
Ahh okay. So, a separate extension is best.
s
Or you perform a comparison on the current view to find out if what you’re choosing between is appropriate
For example, and this should only be used in your console for testing:
SC.Application.getLayout().getCurrentView() instanceof require('ProductDetails.Full.View')
This returns true when I’m on a PDP and false at all other times
If I had code that I wanted to execute sometimes when I’m on a PDP and sometimes in other scenarios, then I could build up a condition that uses this
Albeit in a cleaner way
k
Ahh okay I see.
How do I set options when Im parsing over the Cart Lines?
Copy code
return {
			mountToApp: function (container) {
					var Cart = container.getComponent('Cart');
					if (Cart) {
						console.log("Cart Component");
						Cart.getLines().then(function(lines) {
							console.log("Line: " , lines);
						});
					}
			}
	}
});
That works, and gives me the quantity and other fields on each Line. But how do I actually set values in a specifically template/view when im in that loop?
s
Set values of item options for items … already in the cart?
k
yes
Just want to display a
StockMessage
by comparing the quantity available to the quantity of each line
and set the
ShowOutOfStockMessage
and Message for each line, if that conditional is met.
s
Well typically you use updateLine()
k
I was able to do that by returning a single
boolean
by doing this
Copy code
PDP.addToViewContextDefinition(
						"ProductLine.Stock.View",
						"showOutOfStockMessage",
						"boolean",
But not sure how to do the best way in the Cart...
s
Although I don’t remember exactly what happens if you to try to an update line by changing its item options
If they are matrix item options, you may have to remove the item first and add a new one with new options, but I don’t recall
k
Well they wouldnt be new options, just setting the
showoutofstockmessage
boolean on each line
s
Change the ShowOutOfStockMessage field?
k
Yes
s
That’s not cart data
k
"This item only has X available, we will back order any additional units ordered"
So its not possible in the Cart then?
s
I see, I think that’s more superficial than you think
Unless you want that data recorded on the sales order for example
k
Just want to compare backorderable items' quantity available to items in cart
Which data?
s
The message you showed to the customer
k
Ahh
Ideally we would want it on the Confirmation modal as well as the cart
s
OK that’s a separate concern
k
So customers are notified that they are trying to order more than the "Buildable qty" for specific kit items
s
First you want the data to show for each line item
k
Yes
s
So, to be clear, you don’t need to ‘set’ any data on the cart
That’s for data you want to send to NetSuite
So you need to focus on adding a new property to the context object for the line items and/or have a view and template show that
The line item quantities are probably already available in the context object for the line item
So the calculation could likely be done with when you’re adding in the property to the view (using the context object you’re passing in)
k
Correct, quantities are available.
Ok and how would I
add a new property to the context object
?
Whoops didnt mean to check that
Would I simply just get the data I need in that
GetLines
method, then just
addToViewContextDefinition
in a few views and return an object containing a boolean, and a field for text?
s
yes that is the right method
As I said, though, I think the quantities will already be available in the view’s context object, so you may not need to use getLines()
But it depends on the view
k
I think I would want
<div class="cart-lines-stock" data-view="<http://Product.Stock.Info|Product.Stock.Info>"></div>
Thats my other question, It seems I want
Cart.Lines.View
and
Product.Stock.View
Or rather I want to update the
Product.Stock.View
from two different places... the PDP and the Cart, which is weird.
@Steve Goldberg - Is there anything wrong with using the following conditional in an extension? It seems to work
Copy code
SC.Application.getLayout().getCurrentView() instanceof require('Cart.Detailed.View')
s
Yes two things
We don’t recommend using the SC global variable in extension code
We don’t recommend using the require keyword in extension code
The application object is available in your extension (named as
container
when it is passed into the
mountToApp
function) and if you want to ‘require’ a module, you should add it as a dependency to your custom module
k
so instead of my opening being
Copy code
define(
	'Fwc.OutOfStockCart.OutOfStockCart'
,   [
		'Fwc.OutOfStockCart.OutOfStockCart.View'
	]
,   function (
		OutOfStockCartView
	)
{
	'use strict';

	return  {
		mountToApp: function mountToApp (container)
		{
			// using the 'Layout' component we add a new child view inside the 'Header' existing view 
			// (there will be a DOM element with the HTML attribute data-view="Header.Logo")
			// more documentation of the Extensibility API in
			// <https://system.netsuite.com/help/helpcenter/en_US/APIs/SuiteCommerce/Extensibility/Frontend/index.html>
			
			/** @type {LayoutComponent} */
			var layout = container.getComponent('Layout');
			var Cart = container.getComponent('Cart');
			var ctx;
			// create a new map for the cart lines with the internalid as the key
			var cartLines = new Map();
			ctx = {
				isCart: false,
			};

			if(layout)
			{
				layout.addToViewContextDefinition(
          "ProductLine.Stock.View",
          "FWCExtras",
          "object",
          function (context) {
						console.log("Is Cart?", SC.Application.getLayout().getCurrentView() instanceof require('Cart.Detailed.View'))
						ctx.isCart
I would add what to the dependency array?
I have 80% of my extension working, but im running into a LOT of weirdness. • It runs twice on every page load • It works on local and not production/dev • it "errors" out after I make a change to the cart • The above require and checking to see if the cart page SEEMS to be working just like you wrote it. Could this be causing the weirdness?
SC.Application.getLayout().getCurrentView() instanceof require('Cart.Detailed.View')
works in my extension
All I want to do is use the "ProductLine.Stock.View" view, check if in the cart, then iterate over each line in the cart. But thats proving to be VERY difficult.
s
I would add what to the dependency array?
The module you want to compare — the one you are using
require
for. In your example, Cart.Detailed.View.
• It runs twice on every page load
This can happen sometimes with some code. I do not know why but it’s something I’ve observed before. If it really bothers you, you could create a variable that tracks how many times something has fired and ensure it only fires it once.
SC.Application.getLayout().getCurrentView() instanceof require('Cart.Detailed.View')
works in my extension
It will. It’s not ‘incorrect’, it’s just following unrecommended coding practices.
All I want to do is use the “ProductLine.Stock.View” view, check if in the cart, then iterate over each line in the cart. But thats proving to be VERY difficult.
I recommend completing our training course or, at least, following my beginners’ tutorial before attempting to create customisations.
k
@Steve Goldberg can you link me?