I'm newbie in Angularjs,The following Spring controller get object from database I want to print this object attributes in angularjs controller but I get undefined
#RequestMapping(value = "/rest/getById",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#RolesAllowed(AuthoritiesConstants.ADMIN)
public ChartConfigs findOne(Integer id) {
return chartConfigService.getOne(1);
}
This is Angularjs service
myappApp.factory('ChartConfigService', function ($http) {
return {
findOne: function() {
var promise = $http.get('app/rest/chartConfigs/getById').then(function (response) {
return response.data;
});
return promise;
}
}
});
This is Angularjs controller
myappApp.controller('ChartConfigController', function ($scope, ChartConfigService) {
$scope.message = ChartConfigService.findOne();
var obj=ChartConfigService.findOne();
console.log(obj.type);
});
chartconfig domain
package com.innvo.domain;
#Entity
#Table(name = "T_CHART_CONFIGS")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class ChartConfigs {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="id")
private Integer id;
#Column(name = "category")
private String category;
#Column(name = "type")
private String type;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
In your case obj will be a promise too so you have to do it like:
ChartConfigService.findOne().then(function(obj) {
console.log(obj.type);
});
obj.type is undefined because type does not exist on the promise object.
Related
Now I face with some problems about principal data. Maybe it sounds like a fool. But I'm new to Spring..
I wanted to get some specific data from principal data, but it occured an error, So I cant.
this is my customUserDetails that implement UserDetails.
private String id;
private String pw;
private String name;
private String auth;
private String level;
private String label;
private int enabled;
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
ArrayList<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
authList.add(new SimpleGrantedAuthority(auth));
return authList;
}
#Override
public String getPassword() {
return pw;
}
#Override
public String getUsername() {
return id;
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return enabled==1?true:false;
}
public String getName() {
return name;
}
public String getLabel() { return label;} // 4월 19일 동현 추가
public void setName(String name) {
this.name = name;
}
public String getAuth() {
return auth;
}
And this is principal data I got from console.log
CustomUserDetails(id=admin, pw=$2a$10$Z9C0gTGV0weknBvNi4YFY.l41vjrYo4UgO3MlPwgmIn4uDeYlepFq, name=Admin, auth=ROLE_ADMIN, level=null, label=N, enabled=1)
I want to extract label value from Principal, so I tried to do this code, but I can't.
console.log('${sessionScope.SPRING_SECURITY_CONTEXT.authentication.principal.label}');
How can I get 'label' data from principal?
Thank you for your kind support :)
In your Controller or any other bean, autowire user details like
public String doSomething(#AuthenticationPrincipal CustomUserDetails userDetails) {
String label = userDetails.getLabel();
}
I have popup form in my html that looks like this:
<dialog id="favDialog">
<div id="feedback"></div>
<form id="add_watchlist_symbol_form">
<label for="symbol">Enter Symbol:</label>
<input type="text" class="form-control" id="symbol" placeholder="SYMB"/><br><br>
<button type="submit" class="btn btn-default" id="add-watchlist-symbol-btn">Add</button>
</form>
<button id="cancelBtn" value="cancel">Cancel</button>
</dialog>
The dialog pops up successfully when I click a button.
The dialog contains a button called Add. It's click event is handled by javascript which sends an ajax POST request containing the form field values to Spring Boot like this:
function submit_watchlist_symbol() {
console.log("Im in submit_watchlist_symbol");
var formData = {
symbol: $("#symbol").val(),
name: "My Portfolio"
}
//$("#btn-search").prop("disabled", true);
$.ajax({
type: "POST",
contentType: "application/json",
url: "/api/v1/AddSymbolToWatchlist",
data: JSON.stringify(formData),
dataType: 'json',
success: function (result) {
if(result.status=="Done") {
$('#feedback').html(result.data.symbol +" added.");
}
else {
$('#feedback').html("<strong>Error</strong>");
}
console.log("ERROR: ",e);
},
error: function (e) {
alert("Error!")
console.log("ERROR: ",e);
}
});
// Reset FormData after Posting
resetData();
}
When I click that button I get Spring Boot error:
Resolved
[org.springframework.http.converter.HttpMessageNotReadableException:
JSON parse error: null; nested exception is
com.fasterxml.jackson.databind.JsonMappingException: N/A at [Source:
(PushbackInputStream); line: 1, column: 11] (through reference chain:
net.tekknow.moneymachine.model.Watchlist["symbol"])]
I suspect the form data is not being mapped correctly to the Watchlist.java model due to the model containing a composite key, like this:
#Entity
#Table(name = "watchlist")
public class Watchlist {
#EmbeddedId
public WatchlistId watchlistId;
public String getSymbol() {
return watchlistId.getSymbol();
}
public void setSymbol(String symbol) {
watchlistId.setSymbol(symbol);
}
public String getName() {
return watchlistId.getName();
}
public void setName(String watchlistName) {
watchlistId.setName(watchlistName);
}
public String toString() {
return "watchlist:symbol=" +getSymbol() +", name="+getName();
}
}
where watchlistId contains the symbol and name, like this:
#Embeddable
public class WatchlistId implements Serializable {
#Column(name="symbol")
private String symbol;
#Column(name="name")
private String name;
WatchlistId() {
}
WatchlistId(String symbol, String name) {
this.symbol = symbol;
this.name = name;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WatchlistId that = (WatchlistId) o;
return Objects.equals(symbol, that.symbol) && Objects.equals(name, that.name);
}
#Override
public int hashCode() {
return Objects.hash(symbol, name);
}
}
Here is the Spring Boot controller that handles the request:
#PostMapping("/AddSymbolToWatchlist")
#ResponseBody
public AddWatchlistSymbolResponse addSymbolToWatchlist(#RequestBody Watchlist watchlist){
System.out.println("made it to AddWatchlistSymbolResponse");
// Create Response Object
AddWatchlistSymbolResponse response = new AddWatchlistSymbolResponse("Done", watchlist);
return response;
}
The AddWatchlistSymbolResponse class looks like this:
public class AddWatchlistSymbolResponse {
private String status;
private Object data;
public AddWatchlistSymbolResponse(){
}
public AddWatchlistSymbolResponse(String status, Object data){
this.status = status;
this.data = data;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
Suggestions?
I figured it out. I changed the controller to this:
#PostMapping(value = "/AddSymbolToWatchlist")
#ResponseBody
public WatchlistIdResponse addSymbolToWatchlist(#RequestBody WatchlistId watchlistId){
System.out.println("made it to AddWatchlistSymbolResponse");
watchlistService.addSymbolToWatchlist(watchlistId);
// Create Response Object
WatchlistIdResponse response = new WatchlistIdResponse("Done", watchlistId);
return response;
}
And created a separate response for WatchlistId called WatchlistIdResponse.java:
package net.tekknow.moneymachine.model;
public class WatchlistIdResponse {
private String status;
private Object data;
public WatchlistIdResponse() {
}
public WatchlistIdResponse(String status, Object data) {
this.status = status;
this.data = data;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
The reason is that the Watchlist class contains only the WatchlistId property. WatchlistId contains the symbol and name properties that make up the composite index.
i'm in trouble with this problem.
I've a Javascript structur like this:
$scope.setting= {
enabled: false,
host:"",
port:"",
user:"",
pwd:"",
path:"/",
filePrefix:"",
type:"",
sendInterval:"",
dataPeriod:"",
compression:false,
subscription:[]
};
In the controller i modify the subscription array, but when i pass it to the java code:
$http.post('/api/testAndSetFTPSetting', $scope.setting)
.success(function (data) {
console.log(data);
})
.error(function (data, status, header, config) {
});
the subscription array is null.
Here the API
#RequestMapping(value = {"/api/testAndSetFTPSetting"}, method={RequestMethod.POST})
#ResponseBody
public boolean testAndSetFTPSetting(FTPConfiguration ftp) throws JAXBException {
System.out.println(ftp.getSubscribtion().size()); // here i've ever 0 and ftp.getSubscribtion() return me null
return true;
}
Here the Java Class who controls the object:
#XmlRootElement(name="FTPconfiguration")
#XmlAccessorType (XmlAccessType.FIELD)
public class FTPConfiguration{
boolean enabled = false;
String host="127.0.0.1";
int port=22;
String user="root";
String pwd="";
String path="/";
String filePrefix="data";
FTPType type=FTPType.SFTP;
int sendInterval=15;
int dataPeriod=5;
boolean compression=false;
#XmlElementWrapper(name="subscriptions")
List<String> subscription = new LinkedList<String>();
public FTPConfiguration() {
}
public FTPConfiguration(boolean enabled,String host, int port, String user, String pwd, String path, String filePrefix,
FTPType type, int sendInterval, int dataPeriod, boolean compression, List<String> subscription) {
super();
this.host = host;
this.port = port;
this.user = user;
this.pwd = pwd;
this.path = path;
this.filePrefix = filePrefix;
this.type = type;
this.sendInterval = sendInterval;
this.dataPeriod = dataPeriod;
this.compression = compression;
if(subscription != null)
this.subscription.addAll(subscription);
}
// setter and getter method
Where is my fault?
Finally solved!!! The problem was that the javascript array in java is a comma separated String. For this the value that i received was null!
EX
JavaScript OBJ
var arr = ["1", "2", "3"];
$http.post('someUrl', arr)...
Java
#RequestMapping(value = {"/someUrl"}, method={RequestMethod.POST})
public void foo(String s) { // s will be = "1,2,3"
}
This is my .Net Wcf WebService Service1.cs
[DataContract]
public class CompositeType
{
string degree;
string Stre;
string YearOfPass;
string Institute;
string StatusMessage;
string CheckStatus;
[DataMember]
public string deg
{
get { return degree; }
set { degree = value; }
}
[DataMember]
public string stream
{
get
{ return Stre; }
set
{ Stre = value; }
}
[DataMember]
public string yop
{
get
{ return YearOfPass; }
set
{ YearOfPass = value; }
}
[DataMember]
public string inst
{
get
{ return Institute; }
set
{ Institute = value; }
}
[DataMember]
public string StatusMsg
{
get
{ return StatusMessage;}
set
{ StatusMessage = value; }
}
[DataMember]
public string check
{
get
{ return CheckStatus; }
set
{ CheckStatus = value; }
}
}
Here, in Wcf, variables and methods are created. I used AngularJS GET method to call this Wcf Service. The output is Perfect. But using POST method in AngularJS, I get: StatusMsg= "Request object is nullTestCORS_1101.CompositeType"
Here is the AngularJS code:
var app = angular.module('starter', []);
app.controller('customerCtrl',function($scope,$http){
var Composite={"deg":"s","stream":"m","inst":"t","yop":"w"};
console.log(Composite);
$http({
url:'http://192.168.1.50/TestSubCors/Service1.svc/GetDataUsingDataContract',
method: 'POST',
data:Composite,
headers:{'Content-Type':'application/json;charset=utf-8'}
}).then(function(response){
var parsed_data = angular.toJson(response);
console.log("Success")
console.log(parsed_data);
$scope.events=parsed_data;
}),function(response){
$log.error('failure loading', errorresponse);
}
});
Why I am getting this null request object?
In MVC 4, you could install this package Twitter.bootstrap.mvc and this would add lots of HTML helpers.
Once istalled you could send alert to view right from controller.
For example:
public class AccountController : BaseController
{
public ActionResult AlertExample()
{
Success("This is a success alert");
Error("This is error alert");
Information("This is information alert");
...
etc.
}
}
This would send the success alert right from controller to the view.
Objective: Sending Growl Messages from controller
I've tried to implement same thing from the project I mentioned.
So, this is what I've added to my project.
Base controller that other controller derives from
public class BaseController : Controller
{
//
// GET: /Base/
public void Warning(string message)
{
TempData.Add(Alerts.WARNING, message);
}
public void Success(string message)
{
TempData.Add(Alerts.SUCCESS, message);
}
public void Information(string message)
{
TempData.Add(Alerts.INFORMATION, message);
}
public void Error(string message)
{
TempData.Add(Alerts.ERROR, message);
}
}
ControlGroupExtensionClass
namespace BootstrapSupport
{
public class ControlGroup : IDisposable
{
private readonly HtmlHelper _html;
public ControlGroup(HtmlHelper html)
{
_html = html;
}
public void Dispose()
{
_html.ViewContext.Writer.Write(_html.EndControlGroup());
}
}
public static class ControlGroupExtensions
{
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, Expression<Func<T, object>> modelProperty)
{
return BeginControlGroupFor(html, modelProperty, null);
}
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, Expression<Func<T, object>> modelProperty, object htmlAttributes)
{
return BeginControlGroupFor(html, modelProperty,
HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, Expression<Func<T, object>> modelProperty, IDictionary<string, object> htmlAttributes)
{
string propertyName = ExpressionHelper.GetExpressionText(modelProperty);
return BeginControlGroupFor(html, propertyName, null);
}
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, string propertyName)
{
return BeginControlGroupFor(html, propertyName, null);
}
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, string propertyName, object htmlAttributes)
{
return BeginControlGroupFor(html, propertyName, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, string propertyName, IDictionary<string, object> htmlAttributes)
{
var controlGroupWrapper = new TagBuilder("div");
controlGroupWrapper.MergeAttributes(htmlAttributes);
controlGroupWrapper.AddCssClass("control-group");
string partialFieldName = propertyName;
string fullHtmlFieldName =
html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(partialFieldName);
if (!html.ViewData.ModelState.IsValidField(fullHtmlFieldName))
{
controlGroupWrapper.AddCssClass("error");
}
string openingTag = controlGroupWrapper.ToString(TagRenderMode.StartTag);
return MvcHtmlString.Create(openingTag);
}
public static IHtmlString EndControlGroup(this HtmlHelper html)
{
return MvcHtmlString.Create("</div>");
}
public static ControlGroup ControlGroupFor<T>(this HtmlHelper<T> html, Expression<Func<T, object>> modelProperty)
{
return ControlGroupFor(html, modelProperty, null);
}
public static ControlGroup ControlGroupFor<T>(this HtmlHelper<T> html, Expression<Func<T, object>> modelProperty, object htmlAttributes)
{
string propertyName = ExpressionHelper.GetExpressionText(modelProperty);
return ControlGroupFor(html, propertyName, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static ControlGroup ControlGroupFor<T>(this HtmlHelper<T> html, string propertyName)
{
return ControlGroupFor(html, propertyName, null);
}
public static ControlGroup ControlGroupFor<T>(this HtmlHelper<T> html, string propertyName, object htmlAttributes)
{
return ControlGroupFor(html, propertyName, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static ControlGroup ControlGroupFor<T>(this HtmlHelper<T> html, string propertyName, IDictionary<string, object> htmlAttributes)
{
html.ViewContext.Writer.Write(BeginControlGroupFor(html, propertyName, htmlAttributes));
return new ControlGroup(html);
}
}
public static class Alerts
{
public const string SUCCESS = "success";
public const string WARNING = "warning";
public const string ERROR = "error";
public const string INFORMATION = "info";
public static string[] ALL
{
get { return new[] { SUCCESS, WARNING, INFORMATION, ERROR }; }
}
}
}
ViewHelperExtensionClass
namespace BootstrapSupport
{
public static class DefaultScaffoldingExtensions
{
public static string GetControllerName(this Type controllerType)
{
return controllerType.Name.Replace("Controller", String.Empty);
}
public static string GetActionName(this LambdaExpression actionExpression)
{
return ((MethodCallExpression)actionExpression.Body).Method.Name;
}
public static PropertyInfo[] VisibleProperties(this IEnumerable Model)
{
var elementType = Model.GetType().GetElementType();
if (elementType == null)
{
elementType = Model.GetType().GetGenericArguments()[0];
}
return elementType.GetProperties().Where(info => info.Name != elementType.IdentifierPropertyName()).ToArray();
}
public static PropertyInfo[] VisibleProperties(this Object model)
{
return model.GetType().GetProperties().Where(info => info.Name != model.IdentifierPropertyName()).ToArray();
}
public static RouteValueDictionary GetIdValue(this object model)
{
var v = new RouteValueDictionary();
v.Add(model.IdentifierPropertyName(), model.GetId());
return v;
}
public static object GetId(this object model)
{
return model.GetType().GetProperty(model.IdentifierPropertyName()).GetValue(model, new object[0]);
}
public static string IdentifierPropertyName(this Object model)
{
return IdentifierPropertyName(model.GetType());
}
public static string IdentifierPropertyName(this Type type)
{
if (type.GetProperties().Any(info => info.PropertyType.AttributeExists<System.ComponentModel.DataAnnotations.KeyAttribute>()))
{
return
type.GetProperties().First(
info => info.PropertyType.AttributeExists<System.ComponentModel.DataAnnotations.KeyAttribute>())
.Name;
}
else if (type.GetProperties().Any(p => p.Name.Equals("id", StringComparison.CurrentCultureIgnoreCase)))
{
return
type.GetProperties().First(
p => p.Name.Equals("id", StringComparison.CurrentCultureIgnoreCase)).Name;
}
return "";
}
public static string GetLabel(this PropertyInfo propertyInfo)
{
var meta = ModelMetadataProviders.Current.GetMetadataForProperty(null, propertyInfo.DeclaringType, propertyInfo.Name);
return meta.GetDisplayName();
}
public static string ToSeparatedWords(this string value)
{
return Regex.Replace(value, "([A-Z][a-z])", " $1").Trim();
}
}
public static class PropertyInfoExtensions
{
public static bool AttributeExists<T>(this PropertyInfo propertyInfo) where T : class
{
var attribute = propertyInfo.GetCustomAttributes(typeof(T), false)
.FirstOrDefault() as T;
if (attribute == null)
{
return false;
}
return true;
}
public static bool AttributeExists<T>(this Type type) where T : class
{
var attribute = type.GetCustomAttributes(typeof(T), false).FirstOrDefault() as T;
if (attribute == null)
{
return false;
}
return true;
}
public static T GetAttribute<T>(this Type type) where T : class
{
return type.GetCustomAttributes(typeof(T), false).FirstOrDefault() as T;
}
public static T GetAttribute<T>(this PropertyInfo propertyInfo) where T : class
{
return propertyInfo.GetCustomAttributes(typeof(T), false).FirstOrDefault() as T;
}
public static string LabelFromType(Type #type)
{
var att = GetAttribute<DisplayNameAttribute>(#type);
return att != null ? att.DisplayName
: #type.Name.ToSeparatedWords();
}
public static string GetLabel(this Object Model)
{
return LabelFromType(Model.GetType());
}
public static string GetLabel(this IEnumerable Model)
{
var elementType = Model.GetType().GetElementType();
if (elementType == null)
{
elementType = Model.GetType().GetGenericArguments()[0];
}
return LabelFromType(elementType);
}
}
//public static class HtmlHelperExtensions
//{
// public static MvcHtmlString TryPartial(this HtmlHelper helper, string viewName, object model)
// {
// try
// {
// return helper.Partial(viewName, model);
// }
// catch (Exception)
// {
// }
// return MvcHtmlString.Empty;
// }
//}
}
and the _alert partial View
#using BootstrapSupport
#if (TempData.ContainsKey(Alerts.WARNING))
{
<div class="alert alert-block">
<a class="close" data-dismiss="alert" href="#">x</a>
<h4 class="toast-title">Attention!</h4>
#TempData[Alerts.WARNING]
</div>
}
#foreach (string key in Alerts.ALL.Except(new[] { Alerts.WARNING }))
{
if (TempData.ContainsKey(key))
{
<div class="toast toast-top-full-width toast-key">
<button type="button" class="toast-close-button" data-dismiss="alert">x</button>
#TempData[key]
</div>
}
}
After all this I can send alert messages right from controller:
And it works!
For example
public ActionResult Test()
{
Success("Person was successfully added to your addressbook");
}
above code would result this in view
but it is just displaying as content block. Not as I expected to work, as it just appears in view, no effect, nothing. I wanted it to work as in this site Toastr.
I'm guessing I have to implement javascript somewhere in my _alert view and get the message and type(success, error,...) and then use javascript to growl it, to make it behave it as it should.
But i don't have much knowledge about it.
Something like below? Thats just idea, because of my lack of knowledge of Javascript and jquery i couldn't make it work
#*if (TempData.ContainsKey(key))
{
<div class="toastMessageHolder" style="display: none">
<div class="toastMessage">#TempData[key]</div>
<div class="toastMessageType">#key</div>
</div>
if($(".toastMessageHolder"))
{
//loop all toastMessageHolders
$(".toastMessageHolder").foreach(function(){
var message = $(".toastMessage", this).html();
var messageType = $(".toastMessageType", this).html();
});
//feed this parameters to javascript
}*#
Could somebody help me how to make my growling from controller behave as mentioned in example of Toastr?
If I had to growl from any normal view if I hadn't implemented sending msgs from controller to view this is how I would do using toastr:
function foo(response) {
if (response.SomeTest) {
toastr.error(response.ErrorMessage, "Error");
}
else {
$(#Html.IdFor(m=>m.abc)).val('');
}
};
Asp.Net MVC version: 5.1.1
Growling package used: Toastr
This is what I ended up doing.
_alert view(partial). To send alert messages right from controller.
#using BootstrapSupport
<script>
toastr.options = {
closeButton: true,
debug: false,
positionClass: "toast-top-full-width",
onclick: null,
showDuration: "300",
hideDuration: "1000",
timeOut: "5000",
extendedTimeOut: "1000",
showEasing: "swing",
hideEasing: "linear",
showMethod: "fadeIn",
hideMethod: "fadeOut"
}
</script>
#if (TempData.ContainsKey(Alerts.SUCCESS))
{
foreach (var value in TempData.Values)
{
<script>
toastr.success("#value.ToString()");
</script>
}
TempData.Remove(Alerts.SUCCESS);
}
#if (TempData.ContainsKey(Alerts.ERROR))
{
foreach (var value in TempData.Values)
{
<script>
toastr.error("#value.ToString()");
</script>
}
TempData.Remove(Alerts.ERROR);
}
#if (TempData.ContainsKey(Alerts.INFORMATION))
{
foreach (var value in TempData.Values)
{
<script>
toastr.warning("#value.ToString()");
</script>
}
TempData.Remove(Alerts.INFORMATION);
}
#if (TempData.ContainsKey(Alerts.WARNING))
{
foreach (var value in TempData.Values)
{
<script>
toastr.warning("#value.ToString()");
</script>
}
TempData.Remove(Alerts.WARNING);
}