AngularJS via calling to Spring boot Controller responded with thymeleaf.exceptions.TemplateInputException - angularjs

Hello i will tell you step by step,what i did,
1.I have HTML page named ManualChargesListV2.html,when page loads need to load the data in the Dropdown,so i use thymeleaf to show...
Here is #Controller Code
#GetMapping(value="/manualbillentry")
public ModelAndView doFetchUnitCharges(HttpSession session)
{
ModelAndView model = new ModelAndView();
WrpSession wrpsession = new WrpSession();
wrpsession = (WrpSession) session.getAttribute("totalObj");
try {
model.setViewName("ManualChargesListV2");
List<EntSetCharges> flatBillsManualList = new ArrayList<>();
flatBillsManualList = serbilldetails.doFetchUnitCharges(wrpsession);
model.addObject("manuallist",flatBillsManualList);
}
catch (Exception e){
e.printStackTrace();
}
return model;
}
2.The html page loads the data in dropdown perfectly,when choosing dropdown again need to hit the controller to show the data regarding selected dropdown value so i use to code like
<div class="form-group col-md-6">
<label for="chargelist">Select Charge *</label>
<select id="chargelist" class="form-control"
ng-model="selectedcharge"
ng-change="getChargeDetails(selectedcharge)">
<option> Select</option>
<option th:each="manualunitcharge:${manuallist}"
th:value="${manualunitcharge.pkSetCharges}"
th:text="${manualunitcharge.fkAssignCharges.chargeName}"></option>
</select>
</div>
it will call AngularJS ng-change="getChargeDetails(selectedcharge) method,it successfully hits the controller incl selected data.And Sends the data
#GetMapping(value = "manualbillentry/showmanuallist/{chargeid}")
private ResponseMsg doFetchManualChargesList(#PathVariable("chargeid")int chargeid,HttpSession session)
{
ResponseMsg response = new ResponseMsg();
WrpSession wrpsession = new WrpSession();
wrpsession = (WrpSession) session.getAttribute("totalObj");
try {
List<EntFlatIncome> unitChargesList = new ArrayList<>();
unitChargesList = serbilldetails.doFetchManualChargesList(chargeid,wrpsession);
response.setStatus("success");
response.setDataObj(unitChargesList);
}
catch (Exception e){
e.printStackTrace();
response.setStatus("failed");
}
return response;
}
var app = angular.module('ngapppmanual', []);
app.controller('ngctrlmanual', function($scope, $http, $location) {
$scope.ngshowchargelist = false;
$scope.getChargeDetails = function()
{
var url = $location.absUrl() + "/showmanuallist/" + $scope.selectedcharge;
var config = {
headers : {
'Content-Type' : 'application/json;charset=utf-8;'
}
}
$http.get(url, config).then(function(response)
{
if (response.data.status == "success")
{
$scope.manualresult = response.data.dataObj;
$scope.ngshowchargelist = true;
} else
{
$scope.getResultMessage = "Customer Data Error!";
}
},
function(response)
{
$scope.getResultMessage = "Fail!";
});
}
});
I need to Load the Data in in same HTML page But the issue is while responding result as incl Error code 500
org.thymeleaf.exceptions.TemplateInputException: Error resolving template "manualbillentry/showmanuallist/1", template might not exist or might not be accessible by any of the configured Template Resolvers.
i cant understand the issue ,please someone helpme out...

you are using #Controller which returns html, instead you can use #RestController that returns JSON which angularJS is expecting

Related

Render AngularJs index.html in an ASP.NET Core MVC view

I'm currently working on migrating a web app with the following tech:
ASP.NET MVC
AngularJs
Gulp
Azure cloud service
to :
ASP.NET Core MVC
AngularJs
Webpack
Azure App service
The migrated app correctly bundle and serve AngularJs index.html to wwwroot.
Currently, I need to add two views to the ASP.NET Core MVC app and inject the index.html to these views.
I can't figure out how to :
Inject the index.html
Make one of the views as a startup view.
to finally have an URL pattern:
localhost/View1/#/angularJs-state
or
localhost/View2/#/angularJs-state
wwwroot :
Home :
public class BaseController : Controller
{
public IActionResult Index()
{
return View("portal");
}
}
First view :
public class PortalController : Controller
{
public IActionResult Index()
{
return View();
}
}
Startup.cs
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(name: "portal",
pattern: "Portal",
defaults: new { controller = "Portal", action = "Index" });
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Base}/{action=Index}/{id?}");
});
The first view is correctly displayed but without the view name in
the url .
Is it possible to render the index.html from wwwroot in the cshtml
view using #html.Partial ?
According to your description, if you want to render the html page in the view, I suggest you could write a custom render method in mvc and return the index file as the file result to the mvc view.
More details, you could refer to below codes:
1.Create render extension method:
public static class HtmlHelperViewExtensions
{
public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, object parameters = null)
{
var controller = (string)helper.ViewContext.RouteData.Values["controller"];
return RenderAction(helper, action, controller, parameters);
}
public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, string controller, object parameters = null)
{
var area = (string)helper.ViewContext.RouteData.Values["area"];
return RenderAction(helper, action, controller, area, parameters);
}
public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, string controller, string area, object parameters = null)
{
if (action == null)
throw new ArgumentNullException(nameof(controller));
if (controller == null)
throw new ArgumentNullException(nameof(action));
var task = RenderActionAsync(helper, action, controller, area, parameters);
return task.Result;
}
private static async Task<IHtmlContent> RenderActionAsync(this IHtmlHelper helper, string action, string controller, string area, object parameters = null)
{
// fetching required services for invocation
var currentHttpContext = helper.ViewContext.HttpContext;
var httpContextFactory = GetServiceOrFail<IHttpContextFactory>(currentHttpContext);
var actionInvokerFactory = GetServiceOrFail<IActionInvokerFactory>(currentHttpContext);
var actionSelector = GetServiceOrFail<IActionDescriptorCollectionProvider>(currentHttpContext);
// creating new action invocation context
var routeData = new RouteData();
var routeParams = new RouteValueDictionary(parameters ?? new { });
var routeValues = new RouteValueDictionary(new { area, controller, action });
var newHttpContext = httpContextFactory.Create(currentHttpContext.Features);
newHttpContext.Response.Body = new MemoryStream();
foreach (var router in helper.ViewContext.RouteData.Routers)
routeData.PushState(router, null, null);
routeData.PushState(null, routeValues, null);
routeData.PushState(null, routeParams, null);
var actionDescriptor = actionSelector.ActionDescriptors.Items.First(i => i.RouteValues["Controller"] == controller && i.RouteValues["Action"] == action);
var actionContext = new ActionContext(newHttpContext, routeData, actionDescriptor);
// invoke action and retreive the response body
var invoker = actionInvokerFactory.CreateInvoker(actionContext);
string content = null;
await invoker.InvokeAsync().ContinueWith(task =>
{
if (task.IsFaulted)
{
content = task.Exception.Message;
}
else if (task.IsCompleted)
{
newHttpContext.Response.Body.Position = 0;
using (var reader = new StreamReader(newHttpContext.Response.Body))
content = reader.ReadToEnd();
}
});
return new HtmlString(content);
}
private static TService GetServiceOrFail<TService>(HttpContext httpContext)
{
if (httpContext == null)
throw new ArgumentNullException(nameof(httpContext));
var service = httpContext.RequestServices.GetService(typeof(TService));
if (service == null)
throw new InvalidOperationException($"Could not locate service: {nameof(TService)}");
return (TService)service;
}
}
2.Add controller method as below:
public IActionResult IndexFile()
{
return File("index.html", "text/html");
}
3.Add below codes into view:
#Html.RenderAction("IndexFile", "Yourcontrollername")

Cannot fetch photo from database using restful api

Im trying to fetch photo of a particular userId which is stored in the database,
Im able to generate response from the API as shown:
but it is received in the error part of the getPhotopath() method of controller as shown:
HTML:
<div class="col-md-3 " ng-init="modifyphoto()" >
<img class="smaller" ng-src="fetchedimg" ng-model="fetchedimg"><br>
<p>{{userName}}</p>
<div ng-model="userType">
<p>{{userType | UserFilter}}</p>
</div>
<div ng-controller="AskController">
<button class="btn btn-default" ng-click="gotouserdetails()">View
My Details</button>
</div>
</div>
Controller:
$scope.modifyphoto = function() {
$scope.getPhotoPath();
if($scope.userPhoto==null){
$scope.fetchedimg=$scope.defaultimg;
}
else{
$scope.fetchedimg=$scope.userPhoto;
}
};
$scope.getPhotoPath = function() {
var obj = JSON.parse($cookies.get('user'));
$scope.passUserId = obj.userId;
$http.get(URI + "user/getphoto"+"/"+$scope.passUserId).then(
function(response) {
alert("hifrsegfsfgv");
alert(response.data.message);
$scope.userPhoto=response.data.userPhoto;
}, function(response) {
alert("hi");
alert(response.data);
$scope.userPhoto =null;
alert("danger"+response.data.userPhoto);
});
};
API:
#Path("getphoto/{an}")
#GET
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response getPhoto(#PathParam("an") String userId) throws Exception {
String returnValue = null;
Response response = null;
User user = null;
try {
System.out.println(userId);
UserService userService = Factory.createUserService();
String photoPath=userService.getPhotoPath(userId);
user = new User();
user.setUserPhoto(photoPath);
System.out.println(photoPath);
returnValue = JSONParser.toJson(user);
System.out.println(returnValue);
response = Response.status(Status.OK).entity(returnValue).build();
} catch (Exception e) {
String errorMessage = AppConfig.PROPERTIES.getProperty(e.getMessage());
User user1 = new User();
user1.setMessage(errorMessage);
String returnString = JSONParser.toJson(user1);
response = Response.status(Status.SERVICE_UNAVAILABLE).entity(returnString).build();
}
return response;
}
Im not understanding if the status is OK in backend then why it is recieved in the error part?
Try returning your image in base64 format to avoid JSON Parse errors. and bind that image to the img tag

Getting status 500 when using angularjs $http to get data from server

I am working on an asp.net mvc application and I am using Entity Framework and AngularJS in it. I am using AngularJS's $http service to call an action method and retrieve data from the server. The correct data is retrieved from the server (I confirmed this by debugging), but somehow an error occurs after the action method returns the retrieved data and the error callback function is fired instead of the success callback function. And then I get a status 500 in the browser's console.
Here are the involved blocks of codes:
(From angularjs controller)
$http({
url: rootUrl + "User/GetUser",//'#Url.Action("GetUser","User")',
method: 'POST',
params: {
uname: $scope.username,
pword: $scope.pass
}
}).then(function (response) {
alert('success!');
$scope.user = response.data;
if ($scope.user.Fullname != undefined) {
$http({
url: rootUrl + "Session/Set",
method: "POST",
data: {
"key": "curr_user",
"value": JSON.stringify($scope.user)
}
});
window.location.href = rootUrl + 'Product/List/';
} else {
//invalid login
$("input[name='password']").select();
$("#validation-summary").html("Wrong email or password.");
$scope.invalidlogin = true;
$(btnLogin).removeClass('disabled');
$(btnLogin).text("Submit");
}
(From mvc controller)
[HttpPost]
public JsonResult GetUser(string uname, string pword)
{
JBManager manager = null;
using (SE_Context db = new SE_Context())
{
try
{
manager = db.Managers
.Include("Transactions.Items")
.Where(m => m.Username == uname && m.Password == pword)
.FirstOrDefault();
//At this point, manager has the desired data
return Json(manager, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return null;
}
}
}
And here's a screenshot of the error in the browser:
Would really appreciate any help. Thanks!
UPDATE:
Everything was working fine before I used Entity Framework. (Just in case it has something to do with the issue)
I think your issue is nested objects.You can flatten object graphs that contain nested objects using DTOs (Data Transfer Objects).
You can just try simple example as like below.If it'll work then you need to extend it to work with your EF query.
public class MyDto
{
public string Name { get; set; }
}
[HttpPost]
public JsonResult GetUser(string uname, string pword)
{
JBManager manager = null;
using (SE_Context db = new SE_Context())
{
try
{
//construct the DTO here
manager = db.Managers.Select(a=> new MyDto(
{
Name = a.Name
})).FirstOrDefault(m => m.Username == uname && m.Password == pword);
return Json(manager, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return null;
}
}
}
You can read more about DTOs here : Create Data Transfer Objects (DTOs)

asp.net mvc use angularjs post json type to controller insert database

I have a problem code.
like this
View
<div ng-app="MyPct4" ng-controller="ajaxCtrl">
<div>
<table>
<tr>
<td><b>pls input Color</b></td>
<td><input type="text" ng-model="InputColor" /></td>
</tr>
</table>
<input type="button" value="save" ng-click="AddUpdateColor()" />
</div>
</div>
Angularjs controller
var ptc4 = angular.module("MyPct4", []);
ptc4.controller('ajaxCtrl', function ($scope, myService) {
$scope.AddUpdateColor = function () {
var newColor = { Color: $scope.InputColor };
var getData = myService.AddColor(newColor);
getData.then(function (msg) {
alert(msg.data);
}, function () {
alert("error")
});
}
}
Angularjs service
ptc4.service("myService", function ($http) {
this.AddColor = function (newColor) {
var response = $http({
method: "post",
url: "/Practice/AddColor",
data: JSON.stringify(newColor),
dataType: "json"
});
return response;
}
}
MVC controller
private TestDBEntities2 db = new TestDBEntities2();
public string AddColor(ColorDB color)
{
if (color != null)
{
db.ColorDB.Add(color);
db.SaveChanges();
return "add success";
}
else
{
return "add fail";
}
}
The result is always show alert add fail.
Seems to be json can't post to MVC controller.
Please help thank you so much.
ColorDB
public partial class ColorDB
{
public int Id { get; set; }
public string Color { get; set; }
}
update:
I changed AddColor controller code.I also tyr to add ColorDB color = new ColorDB();
and color.Color = "testColor";The value can insert to db but ColorDB colalso null.The problem seems to Mvc Controller can't Receive ajax data.
public string AddColor(ColorDB col)
{
ColorDB color = new ColorDB();
color.Color = "testColor";
if (color != null)
{
db.ColorDB.Add(color);
db.SaveChanges();
return "add success";
}
else
{
return "add fail";
}
}
public string AddColor(ColorDB color) you are expecting ColorDB object. If it represents your DB then its wrong. It could not bind. Check the parametres type .
UPDATE: I think the problem is binding.The controller can't bind your json to ColourDB object.
You can try:
Add this your ajax options contentType: "application/json; charset=utf-8". Maybe dataType: "json" is not enough. And if it wont work try to use angular.TOJSON(newColor) instead of using JSON.stringify(newColor). Or combine this two.

pushing a nested array into a nested array angularjs

I have a controller that creates a new allegation for a complaint. I can push into the nested (Child table T2), but am not sure why I can't push into a Child table of the child table (T3).
The model in Json look like this:
{
"c_ID": 1,
"received_DT": "2018-01-22T00:00:00",
"aIO": [{
"a_ID": 1,
"c_ID": 9,
"allegs": [{
"alleG_ID": 33,
"Allegation": "Failure..*",
"disc": []
}]
}]
}
My add angular scope looks as below but I am unsure how I am supposed to push the results.
$scope.addAlleg = function () {
var AIOID = this.a.aiO_ID
$scope.errorMessage = "";
var baseURL = "http://localhost:8000/";
$http.post(baseURL + "api/aio/" + AIOID + "/allegs", $scope.newAlleg)
.then(function (alleg) {
$scope.c.aIO[0].allegs.push(alleg);
$scope.newAlleg = {};
}, function (error) {
$scope.errorMessage = "Failed to save new trip" + error;
})
.finally(function () {
$scope.isBusy = false;
})
};
When I copy the link into postman it posts and creates an allegation just fine, but I know my success/do something with the result is wrong.
Controller
[HttpPost("aio/{aioid}/allegs")]
public JsonResult Post(int aioid, [FromBody]AllegationsViewModel vm)
{
try
{
if (ModelState.IsValid)
{
//Map to entity
var newAllegations = Mapper.Map<ALLEGATIONS>(vm);
//Save to Database
_repository.AddAllegations(aioid, newAllegations);
if (_repository.SaveAll())
{
Response.StatusCode = (int)HttpStatusCode.Created;
return Json(Mapper.Map<AllegationsViewModel>(newAllegations));
}
}
}
catch (Exception ex)
{
_logger.LogError("Failed to save new allegation", ex);
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json("Failed to save new allegation");
}
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(" Validation Failed on new checklist");
}
I have tried
$scope.c.aIO[0].allegs.push(alleg);
$scope.c.aIO[0].allegs[0].push(alleg);
$scope.c.aIO.allegs.push(alleg);
but keep getting bad request. My add scope to the T2 (1st Child table) works just fine as I have
$scope.c.aIO.push(response.data);
Also, my html markup looks like this:
<input type="text" ng-model="newAlleg.Allegation"/>
Have you tried $scope.complaints.aIO[0].allegs.push(alleg.data) ?
I am assuming $scope.c is $scope.complaints

Resources