Call to a member function move() on null laravel 9 - laravel-9

I am new to Laravel, I am getting this error "Call to a member function move() on null laravel 9" and can't understand what is going wrong here, could you help ? My Column name in the table is productimage
Product.Blade.php
<form action="{{url('/add_product')}}" method="POST" enctype="multipart/form-data">
#csrf
<div class="d-flex justify-content-center">
<label for="">Product Image</label>
<input type="file" name="proimage">
</div>
</form>
AdminController.php
use App\Models\products;
public function add_product(Request $request){
$product = new products;
$image = $request->proimage;
$imagename = time().'.'.$image->getClientOriginalExtension();
$request->productimage->move('proimagefolder', $imagename);
$product->productimage=$imagename;
$product->save();
return redirect()->back()->with('message', 'Product Added Successfully');
}

Related

Retrive ids and check related boxes

Using
Laravel 8.54
Livewire 2.6
Laratrust package for roles and permissions
I want to edit the permissions role like that
RolesEdit.php (livewire component)
<?php
namespace App\Http\Livewire\Admin\Roles;
use App\Models\Role;
use Livewire\Component;
use App\Models\Permission;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;
class RolesEdit extends Component
{
public $data = [];
public $role;
public $selectedIds = [];
public function mount(Role $role)
{
$this->role = $role;
$this->data = $role->toArray();
}
public function update()
{
$this->data['permissions'] = $this->selectedIds;
$validated = Arr::except($this->validatedData(), ['permissions']);
$this->role->update($validated);
$this->role->permissions()->sync($this->data['permissions']);
}
public function validatedData()
{
return Validator::make($this->data, [
'display_name' => 'required',
'description' => 'required',
"permissions" => "required|array|min:1",
"permissions.*" => "required|distinct|min:1",
])->validate();
}
public function render()
{
$permissions = Permission::all();
return view('livewire.admin.roles.roles-edit', compact('permissions'));
}
}
Roles-edit.blade.php
<div class="mt-1">
<label class="form-label">{{ __('site.display_name') }}</label>
<input wire:model="data.display_name" type="text" class="form-control" placeholder="Enter role name" />
</div>
<div class="mt-1">
<label class="form-label">{{ __('site.role_description') }}</label>
<textarea wire:model="data.description" type="text" class="form-control"
placeholder="Enter Description"></textarea>
</div>
<div class="row w-100">
#foreach ($permissions as $permission)
<div class="col-md-3">
<div class="form-check ms-5">
<input wire:model.defer="selectedIds" class="form-check-input" id="{{ $permission->name }}"
value="{{ $permission->id }}" type="checkbox"
{{ $role->permissions->contains($permission->id) ? 'checked' : '' }} />
<label class="form-check-label" for="{{ $permission->name }}">
{{ $permission->display_name }}</label>
</div>
</div>
#endforeach
</div>
When I open roles-edit view I want to check boxes that have $permission->id related to role so I use
{{ $role->permissions->contains($permission->id) ? 'checked' : '' }}
But it did not work … all checkboxes is unchecked
instead using code:
{{ $role->permissions->contains($permission->id) ? 'checked' : '' }}
try this
#if($role->permissions->contains($permission->id)) checked #endif
also try to add wire:key directive to the parent div of the input element
<div class="form-check ms-5" wire:key="input-checkbox-{{ $permission->id }}">
I suggest you, create an array to retrieve the permissions ids of the role
public $permissionsIds = [];
public function mount(Role $role)
{
$this->role = $role;
$this->data = $role->toArray();
$this->permissionsIds = $this->role->permissions()->pluck('id');
}
// in blade
#if(in_array($permission->id,$permissionsIds)) checked #endif

Insert ForEach Value in View into the Database MVC

Hi currently I am doing a shopping cart for my project
I would like to ask how can I import the values in a ForEach to the database.
For example, I have the following data in my view.
#foreach (Cart_Has_Services c in Model)
{
<div class="cart-row">
<div class="cart-items">#c.Cart_Service</div>
<div class="cart-items">#c.Additional_Notes</div>
<div class="cart-items">#c.Unit_Price</div>
<div class="cart-items">
<form asp-controller="Cart" asp-action="UpdateCart" formaction="post">
<input type="number" class="item-quantity-input" value="#c.Quantity" />
<input type="submit" class="btn btn-secondary" value="Update" />
</form>
</div>
<div class="cart-items">
<a asp-controller="Cart"
asp-action="DeleteItem"
asp-route-id="#c.Cart_Id"
onclick="return confirm('Delete Serivce #c.Cart_Service')">
Delete
</a>
</div>
</div>
}
As for now, I want to INSERT data (Cart Service, Additional Notes and Quantity) into my database (Order).
In my controller:
public IActionResult Checkout(Cart_Has_Services cart)
{
List<Cart_Has_Services> carts = DBUtl.GetList<Cart_Has_Services>("SELECT * FROM Cart");
string sql = #"INSERT INTO [Order](Order_Name,Order_Description,Order_Quantity)
VALUES('{0}','{1}',{2})";
int ord = DBUtl.ExecSQL(sql, cart.Cart_Service, cart.Additional_Notes, cart.Quantity);
if (ord == 1)
{
TempData["Message"] = "Perofrmance Successfully Created";
TempData["MsgType"] = "success";
return RedirectToAction("Success");
}
else
{
ViewData["Message"] = DBUtl.DB_Message;
ViewData["MsgType"] = "danger";
return View("ShoppingCart");
}
}
I tried the method that I have inserted but it created without inserting the data.
How can I solve this problem?
Hope can get some guidance.
Thank you
The form in the view only submit Quantity, without Cart_Service and Additional_Notes.
To submit their value, you may set hidden inputs in the form. Also you should set name attribute for the input for model binding.
#foreach (Cart_Has_Services c in Model)
{
<div class="cart-row">
<div class="cart-items">#c.Cart_Service</div>
<div class="cart-items">#c.Additional_Notes</div>
<div class="cart-items">#c.Unit_Price</div>
<div class="cart-items">
<form asp-controller="Cart" asp-action="UpdateCart" formaction="post">
<input type="hidden" name="Cart_Service" value="#c.Cart_Service" />
<input type="hidden" name="Additional_Notes" value="#c.Additional_Notes" />
<input type="number" name="Quantity" class="item-quantity-input" value="#c.Quantity" />
<input type="submit" class="btn btn-secondary" value="Update" />
</form>
</div>
<div class="cart-items">
<a asp-controller="Cart"
asp-action="DeleteItem"
asp-route-id="#c.Cart_Id"
onclick="return confirm('Delete Serivce #c.Cart_Service')">
Delete
</a>
</div>
</div>
}

NET Core - Ajax post not binding child model

Child model binding is not working properly on Ajax post call in .Net core controller method
I am using below model -
public class UserViewModel
{
public UserViewModel()
{
UserAttribute = new CAMPv2.Models.AutoPoco.UserAttribute();
}
public UserAttribute UserAttribute { get; set; }
}
public class UserAttribute
{
[JsonPropertyName("FirstName")]
public string FirstName { get; set; }
}
Below is the Ajax call -
#using User.Models
#model UserViewModel
#{
ViewData["Title"] = "UserDetails";
}
<form class="kt-form" id="kt_form">
<div class="kt-wizard-v3__content" data-ktwizard-type="step-content" data-ktwizard-state="current">
<div class="kt-form__section kt-form__section--first">
<div class="form-group row required">
<label for="FirstName" class="col-md-3 col-form-label k-font-bold text-md-right control-label">First Name</label>
<div class="col-6">
<input type="text" class="form-control" name="FirstName" placeholder="" required asp-for="UserAttribute.FirstName">
</div>
</div>
</div>
<div class="btn btn-brand btn-md btn-tall btn-wide btn-bold btn-upper" data-ktwizard-type="action-submit" id="btnSubmit">Submit</div>
</div>
</form>
<script>
$("#btnSubmit").click(function () {
var formData = $("#kt_form").serialize();
alert(formData);
$.ajax({
url: "/User/CreateUser/",
data: formData,
type: "POST",
dataType: "json",
success: function (result) {
if (result.success) {
alert('data submitted successfully');
}
},
error: function (result) {
alert('failed to submit data');
},
});
});
</script>
Below is action method -
[HttpPost]
public ActionResult CreateUser(UserViewModel model)
{
try
{
return Json(new { success = true, result = model, errorMessage = "" });
}
catch (WebException ex)
{
return Json(new { success = false, errorMessage = ex.Message });
}
}
Model values are null. Can anyone please let me know what i am missing here? Ajax post call is returning model to action method with null values.
Model values are null. Can anyone please let me know what i am missing here? Ajax post call is returning model to action method with null values.
As far as I know, if you use $("#kt_form").serialize() it will serialize the form into from data according to input tag's name attribute.
But you have set the input tag's name to FirstName. That means the asp.net core model binding will bind the value to FirstName property. But the value is used for UserAttribute's FirstName not the viewmodel's FirstName. This is the reason why your model binding result is null.
To solve this issue, I suggest you could try to use asp.net core tag helper to help you generate the input tag name or you could modify the name property to UserAttribute.FirstName.
You could modify the input as below:
<input type="text" class="form-control" placeholder="" required asp-for="#Model.UserAttribute.FirstName">
Detail view codes:
<form class="kt-form" id="kt_form">
<div class="kt-wizard-v3__content" data-ktwizard-type="step-content" data-ktwizard-state="current">
<div class="kt-form__section kt-form__section--first">
<div class="form-group row required">
<label for="FirstName" class="col-md-3 col-form-label k-font-bold text-md-right control-label">First Name</label>
<div class="col-6">
<input type="text" class="form-control" placeholder="" required asp-for="#Model.UserAttribute.FirstName">
</div>
</div>
</div>
<div class="btn btn-brand btn-md btn-tall btn-wide btn-bold btn-upper" data-ktwizard-type="action-submit" id="btnSubmit">Submit</div>
</div>
</form>
Result:

Why is the Bind attribute seemingly breaking my model binding of nested objects?

Could someone help me resolve this issue. I'm trying to limit over posting with bind param action but it seems that it doesn't work at all. When I removed the Bind keyword, everything started to work as a charm.
Here is the code sample:
View Model:
public class ProductCreateViewModel
{
public Product Product { get; set; }
public ICollection<IFormFile> Images { get; set; }
}
Action:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Product.Id,Product.CategoryId,Product.Description,Product.Title")] ProductCreateViewModel productVM)
{
if (ModelState.IsValid)
{
_context.Add(productVM.Product);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewData["CategoryId"] = new SelectList(_context.Categories.Include(c => c.Categories).Where(c => c.ParentCategoryId == null), "Id", "Name", productVM.Product.CategoryId);
return View(productVM);
}
View:
#model CatalogWebApp.Models.ProductsViewModels.ProductCreateViewModel
#{
ViewData["Title"] = "Add Product";
ViewData["BigPageTitle"] = "Products";
ViewData["PageBoxTitle"] = "Add New Product";
}
<form asp-action="Create">
<div class="form-horizontal">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Product.CategoryId" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select name="Product.CategoryId" class ="form-control">
#foreach(Category item in (ViewBag.CategoryId as SelectList).Items)
{
<option value="#item.Id">#item.Name</option>
if (item.Categories != null && item.Categories.Count > 0)
{
foreach (var subCat in item.Categories)
{
<option value="#subCat.Id">--#subCat.Name</option>
}
}
}
</select>
</div>
</div>
<div class="form-group">
<label asp-for="Product.Description" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Product.Description" class="form-control" />
<span asp-validation-for="Product.Description" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Product.Title" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Product.Title" class="form-control" />
<span asp-validation-for="Product.Title" class="text-danger" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</form>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Could someone pelase indicate if I have a problem or it is only a known asp.net core issue?
I'm not quite sure why you using Bind for your case.
Just create sepatate ViewModel with only properties you need like ProductCreateStort.
Then use this ViewModel in your controller signature and inherit your main model from it.
This way you won't mess with Bind and limit your params on POST
While I'm fairly new to ASP.NET Core myself (and coming to this question 7 months late), I ran into this same issue. I think the key here is that you have to bind "Product" for it to be considered. Binding "Product.Id" by itself doesn't appear to be good enough. So this should work:
[Bind("Product,Product.Id,Product.CategoryId,Product.Description,Product.Title")]
Of course, Hamid Mosalla's comment is a better option if ALL of your bound properties are on the nested object (which leads to wonder why you need a view model in the first place). In my case, I have a nested object AND a local property, so using the "Prefix" solution wasn't the right thing to do.
Anyway, hope this helps someone.
You need to pass your values as params string[], not as a single string separated by commas:
[Bind("Product.Id","Product.CategoryId","Product.Description","Product.Title")]
See Source

Client side value in URL.Action parameter

I am trying to post feedback on an object from a modal popup. No values on the popup are populated from server side.
<div class="modal fade" id="msg-editor">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>Title of the form</h3>
</div>
<div class="modal-body">
<div class="row-fluid">
<div class="controls span10">
<label class="control-label" for="Title">Title and message</label>
<input type="text"
class="input-xlarge" id="Title" name="Title"
placeholder="Title of the message" />
<textarea class="input-xlarge" id="Message"
name="Message" rows="5" cols="9"
placeholder="Message"></textarea>
<label class="checkbox">
<input type="checkbox" value="option2" id="EmailSelf">
Send a copy of this message to yourself
</label>
</div>
</div>
</div>
<div class="modal-footer">
Close
<a id="Submit" class="btn btn-primary" href="#Url.Action("AddDocumentMessage", "Invoice", new { param1 = $('#myFormSubmit').value, param2 = Model.Obj.Value1, param3 = Model.HashedValue })">Send</a>
</div>
</div>
The part that doesnt work is
param1 = $('#myFormSubmit').value.
How do I pass the client side value?
You can't...!
Because razor code is parsed and rendered in the server side, and in server, there is no jquery or any client code or data...
An alternative similar work can be like the following:
<div class="modal-footer">
Close
<input type="button" value="Send" onclick="submit()" />
</div>
<script>
function submit() {
$.ajax({
url: #Url.Action("act", "con") + '?param1=' + $('#myFormSubmit').value +
'&param2=' #Model.Obj.Value1 +
'&param3=' + #Model.HashedValue,
type: 'POST',
// ... other ajax options ...
});
}
</script>
Then, in your action method you'll receive all params in string:
[HttpPost]
public ActionResult act(string param1, string param2, string param3)
{
ViewBag.Message = "Your contact page.";
return View();
}
The problem you are running into is that the Razor code is executed on the server to create the URL and then sent to the client, so the client side value is not known at the time the URL is created. You need to create a placeholder in the URL so that the client side value can be inserted when the document is ready.
So something like this:
<a id="Submit" class="btn btn-primary" href="#Url.Action("AddDocumentMessage", "Invoice", new { param1 = "param1_placeholder" , param2 = Model.Obj.Value1, param3 = Model.HashedValue })">Send</a>
$(function () {
var url = $('#Submit').attr('href');
$('#Submit').attr('href', url.replace('param1_placeholder', $('#myFormSubmit').value));
});
You may try to generate and append the link you need:
<div class="modal-footer">
Close
<div class="link"></div>
</div>
$(function () {
var path ="#Url.Action("AddDocumentMessage", "Invoice",new {param2 = Model.Obj.Value1, param3 = Model.HashedValue })
$('.link').append('<a id="Submit" class="btn btn-primary" href="'+path+'&param1='+$('#myFormSubmit').val()+'">Send</a>')
});