-1

Edit: the product view contains some products so I'm trying to add them one by one to the cart using a button for each product, the added products shall appear in a table in the partial view (cart) which is working fine, I'm trying now to render this cart inside a popup modal so when i press the popup button it should show me what products i added,when i still inside the product view.

I'm trying to do something like this inside the modal body:

@Html.Partial("_ShowCart", new List<InternetApp.Models.Cart>())

but this retrieves an empty list.

So I want something like this but I don't know how I could do this with different models:

@Html.Partial("_ShowCart", Model)

I have 3 models: product, cart and viewmodel:

public class Product
{
    public int id { get; set; }
    public String name { get; set; }
    public float price { get; set; }
    public String image { get; set; }
    public String description { get; set; }
    public int? CategoryId { get; set; }
}

public class Cart
{
    public int product_id { get; set; }
    public DateTime added_at { get; set; }
    public virtual Product product { get; set; }
}

public class ProductCart
{
    public Product Product { get; set; }
    public Cart Cart { get; set; }
}

The cart and the product each one has controller, I have the cart as a partial view which takes IEnumerable<Cart> and a product view which takes IEnumerable<Product>.

This is the cart index action

public ActionResult Index()
{
    List<Cart> Cart = db.Cart.Include(a => a.product).ToList();
    return PartialView("_ShowCart", Cart);
}

I don't know how to render the cart inside the product because each one has a different IEnumerable model...

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • You should map the data to a viewModel and then bind the viewModel to the view. Can you explain exactly what you are trying to show in the view? And if possible, provide what you are currently trying. – Stephen Raman Jun 01 '20 at 02:48
  • @StephenRaman ok i edited it check it again please, and how could i use the viewmodel while i'm looping through them in both the 2 views to list the products ? – Ziad Mohamed Jun 01 '20 at 04:26

1 Answers1

0

Your Entity Framework (EF) models would look like the following. I modified for suggested standardization and clarity purposes only:

public class Product
{
    [Key] //This is only needed by EF if you don't call the primary key "Id".
    public int Id { get; set; }
    public String Name { get; set; }
    public float Price { get; set; }
    public String Image { get; set; }
    public String Description { get; set; }
    //Add any additional properties.
}

public class Cart
{
    [Key]
    public int Id { get; set; }
    //Add any additional properties
}

public class CartProduct
{
    [Key]
    public int Id { get; set; }
    public int CartId {get; set; } //References Id property in Cart entity.
    public int ProductId {get; set; } //References Id property in Product entity.
    public DateTime AddedAt { get; set; }

    //These are navigation properties.  
    //The foreign key attribute lets EF know what property to reference
    [ForeignKey("CartId")]
    public virtual Cart Cart { get; set; }

    [ForeignKey("ProductId")]
    public virtual Product Product { get; set; }
}

You should create a separate set of models. The EF models should only be used to represent your database tables and properties. Place these models separate from your EF models... maybe a ViewModel folder.

    public class CartProductsViewModel
    {
        public int CartId { get; set; } //Persist the cart you are adding to.
        public IEnumerable<ProductModel> Products {get; set; } //Available products

        public class ProductModel
        {
            public int Id { get; set; }
            public String Name { get; set; }
            public float Price { get; set; }
            public String Image { get; set; }
            public String Description { get; set; }
            //Add any additional properties.
         }

    }

Now you can have ONE controller and ONE view.

public ActionResult Index(int cartId) //passing cartId for cart you are working with.
{
    var viewModel = new CartProductsViwModel();

    viewModel.CartId = cartId;
    //Get available products that you can add to cart.
    viewModel.Products = db.Products //pluralized in DbSet in EF context.
                  .Select(p => new ProductModel
                     { 
                        Id = p.Id,
                        Name p.Name,
                        Price = p.Price,
                        Image = p.Image
                        Description = p.Description
                     });

    return View(viewModel);  
}

In the return, I am not specifying the viewModel name. This is only made possible if you follow MVC guidelines and name the view the same name as the method calling, in this case index.cshtml. And also add following to top:

@model CartProductsViwModel //may need to be fully qualified (add namespace).

You should be able to loop through the Products in this model to show in table. This avoids having to deal with a separate product and cart view. As far as adding the product to the view, this can be done on the client-side. I would suggest to try to get this working first, and then you can create a new question dedicated to the client-side work.

If you really need a dialog, you can look up JQuery dialogs. JQuery UI dialog

You will then need to perform ajax calls to post the added product and the cartId. The method will be something like this.

[HttpPost]
public JsonResult AddProductToCart(int cartId, ProductModel product) {}

That would also be a separate question. I hope this helps get you started.

Stephen Raman
  • 250
  • 2
  • 10