how i insert and update table in one method without form - laravel-6

i have error if i clik like icons in my project
controller
public function like($id,$idpost)
{
$like=new like();
$like->user_id=$id;
$like->post_id=$idpost;
$like->save();
$post=Post::find($idpost);
$jumlah=Post::where('id',$idpost)->value('like');
$post->like=$jumlah+1;
$post->save();
return redirect('post/'.$like->post_id);
}
route
Route::post('like/{id}/{idpost}', 'HomeController#like')->name('likes');
views
<i style="color: #ed4956; font-size: 25px;" class="fa fa-heart"></i>
Database

Related

How To show only one id in laravel

I found a problem when I wanna show my data's detail, it always take two data.
this is my controller
public function show(Transaction $transactions)
{
$tran=Transaction::find($transactions);
return $tran;
return view('admin.transaction.show', compact('tran','transactions'));
}
This is my show Button
<td>
<i class="far fa-eye" style="color:blue"></i>
</td>
and this is the return
How to solve it?

Send List of IDs from List of Object From View to Controller C#

I have a view with a list of objects as its model
#model List<Users>
Inside that view, I have a form and button to submit the form in ASP.NET Core MVC:
<input class="btn btn-success ml-2" style=" width: 100px;"
type="submit" value="#localizer["Save"]" />
I need another button to cancel form submission and redirect to another method but I need to pass the list of Users with redirection at cancel button
I tried
<a asp-controller="User" asp-action="cancel" asp-route-ids="#Model.Select(x => x.id);">Cancel</a>
but it didn't work, the list is empty
If you use asp-route-somekey to set the query, your target list name was recognized as value of the key "Ids",you could see the result as below:
If you do want to pass list to the query,you could try:
<a asp-controller="User" asp-action="Cancel" asp-all-route-data="#(new Dictionary<string, string> { { "Ids[0]", "1" },{ "Ids[1]", "2" } })">Cancel</a>
The result:
However the length of url is limited, it may cause some errors

Selenium Webdriver C# Unable to locate an element on the "active" dropdown class list

I am on the beginner level if it goes for the selenium Webdriver in C#. I can locate elements, write simple scripts in order to input some value, withdraw it, compare and etc. I can also get values from the dropdown list by SelectElement class and so far I have not had any issues.
Recently one of our systems was refactored to React JS and most of my automation tests have stopped working.
Right now I have been struggling with a simple logout operation. I will please my issue below, and I would be grateful for any tips or suggestions.
The hard thing is that I can not locate the logout link which is located in the dropdown list, however, the code for it looks as below. Before you click on the link which acts as an action for the drop-down list it looks like this:
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
UserName UserLast
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li>Logout</li>
</ul>
<div id="user-login" class="hidden">UserName.UserLast</div>
<div id="user-email" class="hidden">UserName.UserLast#companyname.com</div>
</li>
When a User clicks on the the code changes to this one below:
<li class="dropdown open">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="true">
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
UserName UserLast
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li>Logout</li>
</ul>
<div id="user-login" class="hidden">UserName.UserLast</div>
<div id="user-email" class="hidden">UserName.UserLast#companyname.com</div>
</li>
My test is quite simple, locate the Logout "button/link", click on it and perform the logout operation. Now I have started of location the action link which looks like this:
[FindsBy(How = How.XPath, Using = "/html/body/div[1]/div/div[2]/ul[2]/li[2]/a")]
private IWebElement userDropdown;
And my logout method looks like that's,
public void LogOut()
{
userDropdown.Click();
var userDropDownList = Browser.WebDriver.FindElement(By.XPath("/html/body/div[1]/div/div[2]/ul[2]/li[2]/ul"));
var logoutButton = userDropDownList.FindElement(By.LinkText("Logout"));
logoutButton.Click();
}
I perform the click operation on the link, look for the list with the Logout, use the click operation. Still my test does not work and I am not getting any errors at all but the logout operation is not done. I think that the issue here is not the drop-down list is not visible by selenium. I have not tried the SelectElement class because this example is not a select element or maybe I am wrong...
You will need to perform click() on 2 elements to logout:
Identify the dropdown:
[FindsBy(How = How.XPath, Using = "//li[#class='dropdown']/a[#class='dropdown-toggle']/span[#class='glyphicon glyphicon-user']")]
private IWebElement userDropdown;
logOut method:
public void logOut()
{
userDropdown.Click();
var logoutButton = Browser.WebDriver.FindElement(By.XPath("//li[#class='dropdown']//ul[#class='dropdown-menu']/li/a[#href='/Account/Logout']"));
logoutButton.Click();
}
so first things first make sure you've scrolled the item to view
var js = (IJavascriptExecutor)driver;
string idOfLinkToMakeDropDownOpen = "whatever the id is"
IWebElement obj = driver.FindElement(By.XPath("//input[#id='idOfLinkToMakeDropDownOpen']"));
js.ExecuteScript("arguments[0].scrollIntoView(true);", obj);
obj.Click();
Now the drop down should be open so click it
driver.FindElement(By.Xpath("descendant::a[text() = 'Logout']")).Click();
That should click it. You'll probably want to watch it to see if opens the drop down. You also may need to wait a second after the dom to change after having opened the drop down. That would work something like this:
IWebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(15));
after obj.Click(); you do this line:
wait.Until(ExpectedConditions.ElementIsVisible(By.Xpath("descendant::li[#class = 'dropdown open']"));

trouble making in xpath for "ul" html code in selenium webdriver

HTML code:
<div id="routingPanel" class="">
<div id="routingPanelRight">
<ul id="routingList" class="ui-sortable">
<li class="ui-menu-item ui-draggable" style="display: list-item;" role="presentation" data-type="srl" data-id="15">
<a class="ui-corner-all" tabindex="-1">AS-HTTS-US-LAN-SW</a>
<span class="fa fa-trash"/>
<span class="type">[srl]</span>
</li>
<li class="ui-menu-item ui-draggable" style="display: list-item;" role="presentation" data-type="queue" data-id="119">
<a class="ui-corner-all" tabindex="-1">AS-EMEA-NORTH</a>
<span class="fa fa-trash"/>
<span class="type">[queue]</span>
</li></ul></div></div>
I need to click on a button which is having the span class"fa fa-trash" but it is inside li class. And i have list on buttons on the page with li class changing.
I am giving testdata from excel file so i can't use the direct value.
i tried to use this xpath
.//*[#id='routingList']/li[5]/span[1] //testdata1
.//*[#id='routingList']/li[2]/span[1] //testdata2
where li value changes everytime from excel file.
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.visibilityOfElementLocated((By.xpath("//ul[#id='routingList']/li/span[1]")))).click();
List<WebElement> options = driver.findElements(By.xpath("//ul[#id='routingList']/li/span[1]"));
for (WebElement option : options) {
if(testData.equals(option.getText()))
option.click();
Tried above code but it is deleting only one from the list ,where i have passed two more testdata that needs to be deleted.
Need suggestions Please
According to the information you gave me in comments, I think the problem is that you are trying to get a text from an element that doesn't contain text.
Let's say your testData is AS-HTTS-US-LAN-SW. In the HTML you provided and the xpath you mentioned, you are selecting an autoclosing tag <span class="fa fa-trash"/>. Once this tag is selected, you are trying to get the text inside of it, and there is none.
<ul id="routingList" class="ui-sortable">
<li class="ui-menu-item ui-draggable" style="display: list-item;" role="presentation" data-type="srl" data-id="15">
===========================
<a class="ui-corner-all" tabindex="-1">AS-HTTS-US-LAN-SW</a> ----> The text is contained here
<span class="fa fa-trash"/> ---> No text in that tag
===========================
<span class="type">[srl]</span>
</li>
</ul>
So, basically, you have to modify a little bit your xpath from : //ul[#id='routingList']/li/span[1] to : //ul[#id='routingList']/li/a to get the text, and then go back to the parent node to find your button with : ../span[contains(#class, 'fa fa-trash')]
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.visibilityOfElementLocated((By.xpath("//ul[#id='routingList']/li/span[1]")))) // removed the click here because you were clicking on the first element of the list
List<WebElement> options = driver.findElements(By.xpath("//ul[#id='routingList']/li/a"));
for (WebElement option : options) {
if(testData.equals(option.getText()))
option.findElement(By.xpath("../span[contains(#class, 'fa fa-trash')]")).click();
Tell me if it helped
I know you already accepted an answer but there's a more efficient way to do this. You can specify the text you are looking for as part of the XPath. So, you do a single search instead of looping through all the options which can be a performance hit if there are many options. Also, with something like this you are likely to use it more than once so put it in a function.
In this case, the function would take in the string you are looking for and then click the appropriate element.
public void selectRegion(String regionName)
{
driver.findElement(By.xpath("//a[.='" + regionName + "']/following-sibling::span[#class='fa fa-trash']")).click();
}
and you would call it like
selectRegion(testData);
The function looks for an A tag that contains the desired text and then clicks the sibling SPAN with class fa fa-trash.

Use user ID on a layout in ASP.NET Core

I'm working on a website, and once the user logs in, he is able to check some workouts.
However, I'm trying to pass the user ID from the layout to other pages, as following
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li>
<a class="page-scroll">Profile</a>
</li>
<li>
#Html.ActionLink("Workouts", "Index", "Routines", new {id = Model.UserID })
</li>
<li>
<a class="page-scroll">Evaluation</a>
</li>
<li>
<a class="page-scroll">Nutrition</a>
</li>
<li>
<a class="page-scroll">Services</a>
</li>
<li>
<a class="page-scroll">Membership</a>
</li>
</ul>
</div>
And it is not working, I get the following error:
'Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable'
does not contain a definition for 'UserID'
However, my Model does have a UserID property. I can see it working properly on SQL and even if I takeout the HTML.ActionLink from there it works, but when I try to pass that value from the layout it doesn't work.
Any suggestions on how to solve this? I've been reading here and there but no solution so far.
I may be approaching the problem the wrong way. Is there a way to properly pass the ID of the logged in user to multiple Controllers in order to access the information of that user?
So rather than pass the userID around, how about making a service to get the logged in user and then grab whatever data you need from your database? That way you can inject the service wherever you need it.
public interface ILoggedInUserService
{
LoggedInUser GetLoggedInUser();
}
public class LoggedInUserService : ILoggedInUserService
{
private readonly IHttpContextAccessor _httpContextAccessor;
public LoggedInUserService(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public LoggedInUser GetLoggedInUser()
{
string username = GetLoggedInUsername(_httpContextAccessor.HttpContext.User);
if (!string.IsNullOrEmpty(username))
{
return YourServiceToGetUserData.GetUserData(username);
}
return null;
}
private static string GetLoggedInUsername(ClaimsPrincipal principal)
{
return principal?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
}
}
And then in Startup.cs where you set up your services for dependency injection add this:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();