Breeze createEntity Type not recognized - javascript

I'm trying to make my call to the server with BreezeJS but can't get it to work. It says tblMovie is not recognized. I can't find the problem :S
When I want to add a new movie it says so.
show.js
self.viewAddMovieModal = function () {
self.app.showModal(new self.addmovie()).then(function (result) {
if (result != undefined) {
var movie = dataservice.createMovie({
Title: result[0].title,
Director: result[0].director
});
if (movie.entityAspect.validateEntity()) {
self.movies.push(new movie(result[0].title, result[0].director));
dataservice.saveChanges();
} else {
alert("Error");
}
}
});
};
My dataservice.js layer
/// <reference path="../../Scripts/breeze.debug.js"/>
define(["require"], function (require) {
var Dataservice = (function () {
function Dataservice(service) {
this.serviceName = '';
this._isSaving = false;
this.serviceName = service;
this.Manager = new breeze.EntityManager(this.serviceName);
this.EntityQuery = new breeze.EntityQuery();
}
Dataservice.prototype.getAllMovies = function () {
this.EntityQuery = breeze.EntityQuery.from("AllMovies");
return this.Manager.executeQuery(this.EntityQuery);
};
Dataservice.prototype.createMovie = function (initialValues) {
return this.Manager.createEntity('tblMovies', initialValues); //THis is where it goes wrong :(
};
Dataservice.prototype.saveChanges = function (suppressLogIfNothingToSave) {
if (this.Manager.hasChanges()) {
if (this._isSaving) {
setTimeout(this.saveChanges, 50);
return;
}
this.Manager.saveChanges().then(this.saveSucceeded).fail(this.saveFailed).fin(this.saveFinished);
} else if (!suppressLogIfNothingToSave) {
}
};
Dataservice.prototype.saveSucceeded = function (saveResult) {
this._isSaving = false;
};
Dataservice.prototype.saveFailed = function (error) {
};
Dataservice.prototype.saveFinished = function () {
this._isSaving = false;
};
return Dataservice;
})();
return Dataservice;
})
I do have a model tblMovie
using System;
using System.ComponentModel.DataAnnotations;
namespace DurandalMovieApp.Models
{
public class tblMovie
{
[Key]
public int MovieID { get; set; }
public string Title { get; set; }
public string Director { get; set; }
}
}
Hope someone can help!

I think that the problem is that your entity is: tblMovie, not tblMovies.
Try replacing:
return this.Manager.createEntity('tblMovies', initialValues);
With:
return this.Manager.createEntity('tblMovie', initialValues);

Related

How to call server method to list items in a table?

I have a simple ASP.Net Core 3.0 webapp with SignalR which is used to list and view posts. I added the following js script:
"use strict";
const connection = new signalR.HubConnectionBuilder()
.withUrl("/PostsHub")
.withAutomaticReconnect()
.build();
if (!String.prototype.supplant) {
String.prototype.supplant = function (o) {
return this.replace(/{([^{}]*)}/g,
function (a, b) {
var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r : a;
}
);
};
}
connection.start().then(function () {
$postsTable = $('#postsTable'),
$postsTableBody = $postsTable.find('tbody'),
rowTemplate = '<tr id="{Id}"><td>{Date}</td><td>{User}</td><td><button onclick="btn_click({Id})" id="viewPost{Id}">View</button></td></tr>';
connection.invoke("getAllPosts").done(function (posts) {
$postsTableBody.empty();
$.each(posts, function () {
$postsTableBody.append(rowTemplate.supplant(this));
});
});
}).catch(function (err) {
return console.error(err.toString());
});
But with the above code, the posts are not being listed. I can't see where the error is. Could it be the supplant function?
If you'd like to invoke a hub method that would return all posts, and dynamically populate table with returned data, you can refer to following sample.
PostsHub Class
public class PostsHub : Hub
{
public List<Post> GetAllPosts()
{
var posts = new List<Post>() {
new Post(){Id=1,User="feihan",Date="11/25/2019" },
new Post(){Id=2,User="test1",Date="11/23/2019" },
new Post(){Id=3,User="test2",Date="11/25/2019" }
};
return posts;
}
}
Post Class
public class Post
{
public int Id { get; set; }
public string User { get; set; }
public string Date { get; set; }
}
On JavaScript client
if (!String.prototype.supplant) {
String.prototype.supplant = function (o) {
return this.replace(/{([^{}]*)}/g,
function (a, b) {
//convert to lowercase letters
var r = o[b.toLowerCase()];
return typeof r === 'string' || typeof r === 'number' ? r : a;
}
);
};
}
connection.start().then(function () {
$postsTable = $('#postsTable'),
$postsTableBody = $postsTable.find('tbody'),
rowTemplate = '<tr id="{Id}"><td>{Date}</td><td>{User}</td><td><button onclick="btn_click({Id})" id="viewPost{Id}">View</button></td></tr>';
//use connection.invoke(...).then
connection.invoke("getAllPosts").then(function (posts) {
$('#postsTable').find('tbody').empty();
$.each(posts, function () {
$postsTableBody.append(rowTemplate.supplant(this));
});
});
}).catch(function (err) {
return console.error(err.toString());
});
Test Result

Prototypes in Javascript to Typescript Syntax

Does somebody know how do I write this Javascript code into Typescript? Especially the prototype inside of the class causes me problems...
var Module = (function () {
function Module(name) {
this.name = name;
}
Module.prototype.toString = function () {
return this.name;
};
return Module;
})();
var Student = (function () {
function Student(name, studentNumber) {
this.bookedModules = [];
this.name = name;
this.studentNumber = studentNumber;
}
Student.prototype.bookModule = function (bookedModule) {
this.bookedModules.push(bookedModule);
};
Student.prototype.bookedModuleNames = function () {
return this.bookedModules.map(function (module) {
return module.toString();
});
};
return Student;
})();
In typescript you use classes, the compiler will do the prototype work for you.
You code is equivalent to:
class Module {
public name: string;
constructor(name: string) {
this.name = name;
}
toString(): string {
return this.name;
}
}
class Student {
public name: string;
public studentNumber: number;
public bookedModules: Module[];
constructor(name: string, studentNumber: number) {
this.name = name;
this.bookedModules = [];
this.studentNumber = studentNumber;
}
bookModule(book: Module): void {
this.bookedModules.push(book);
}
bookedModuleNames(): string[] {
return this.bookedModules.map(book => book.name);
}
}
(code in playground)
Which compiles into:
var Module = (function () {
function Module(name) {
this.name = name;
}
Module.prototype.toString = function () {
return this.name;
};
return Module;
}());
var Student = (function () {
function Student(name, studentNumber) {
this.name = name;
this.bookedModules = [];
this.studentNumber = studentNumber;
}
Student.prototype.bookModule = function (book) {
this.bookedModules.push(book);
};
Student.prototype.bookedModuleNames = function () {
return this.bookedModules.map(function (book) { return book.name; });
};
return Student;
}());
Use classes - typescript will generate this code for you:
class Module {
constructor(public name) {
}
toString() {
return this.name;
}
}
class Student {
bookedModules: Module[];
constructor(public name, public studentNumber) {
this.bookedModules = [];
}
bookModule(bookedModule: Module) {
this.bookedModules.push(bookedModule);
}
//...
}

Typescript promise bind angular 1.5

I am having a problem that my promise isn't being bound to the correct this.
I have read many articles on this subject and I think I understand the problem, but the solution isn't clear.
Suggestions
Here is the code:
// AngleCouch.ts`enter code here`
namespace AngleCouchDb {
//Note this is not a ng Service
export class AngleCouch {
...
public getAllUsers(): ng.IPromise<any> {
let dbUrl: string = this.urlPrefix + "/_users/_all_docs? include_docs=true";
let status = new CouchStatus();
console.log("in getAllUsers");
return this.http.get(dbUrl);
}
...
}
}
// UserManagementController.ts
module app {
class UserManagementController {
static $inject = [
'$mdSidenav', '$mdToast', '$mdDialog',
'$mdMedia', '$mdBottomSheet', '$state'];
...
public fetchUsers = () => {
let aUser = AngleCouchDb.ActiveUser.getInstance();
if (aUser.loginStatus `enter code here`!== Shows.StaticData.LoggedIn) {
return;
}
console.log("userManagementController: ");
console.log(this.$state);
this.vm.couch = new AngleCouchDb.AngleCouch();
this.vm.version = {};
this.vm.docTypeList = [];
this.vm.couch.urlPrefix = Shows.StaticData.server;
this.vm.user = new AngleCouchDb.UserCred();
this.vm.couch = new AngleCouchDb.AngleCouch();
this.vm.couch.getAllUsers().then(this.getAllUsersCB, (response: any) => {
console.log(response);`enter code here`
});
}
public getAllUsersCB = (response) => {
this.vm.gridObj = this.vm.initGridOpt();
this.vm.gridObj.data = response.data.rows;
}
...
angular.module("app").
controller("app.userManagementController", UserManagementController );
}

How to load angular-formly vm.fields from server

i am trying to use Angular-Formly to build dynamically forms starting from a set of .NET classes.
I serialize the class properties information in json and return that to Formly, but no fields is shown.
I follow suggestions find in: How to load angular-formly vm.fields object from remotely-generated json?
but not seems to work for me.
My form code is:
<form ng-submit="vm.onSubmit()" novalidate>
<formly-form model="vm.model" fields="vm.formFields">
<button type="submit" class="btn btn-primary submit-button">Submit</button>
</formly-form>
</form>
The angular code is:
<script>
/* global angular */
(function () {
'use strict';
var app = angular.module('formlyExample', ['formly', 'formlyBootstrap'], function config(formlyConfigProvider) {
// set templates here
//formlyConfigProvider.setType({
// name: 'custom',
// templateUrl: 'custom.html'
//});
});
app.factory('User', function ($http) {
return {
getFields: getFields
};
function getFields() {
return $http.post('TestFormly.aspx/LoadData', { headers: { 'Cache-Control': 'no-cache' } });
}
});
app.controller('MainCtrl', function MainCtrl($scope, $http, User) {
var vm = this;
// funcation assignment
vm.onSubmit = onSubmit;
vm.loadingData = User.getFields().then(function (result) {
vm.fields = JSON.parse(result.data.d);
vm.originalFields = angular.copy(vm.fields);
});
vm.model = {
};
// function definition
function onSubmit() {
alert(JSON.stringify(vm.model), null, 2);
}
});
})();
</script>
The CSharp.Net code is:
[WebMethod]
public static string LoadData()
{
string retValue = null;
List<FieldItem> m_fields = new List<FieldItem>();
FieldItem item1 = new FieldItem();
item1.key = "text";
item1.type = "input";
item1.templateOptions = new TemplateOptions() { label = "Text", placeholder = "Formly is terrific!" };
FieldItem item2 = new FieldItem();
item2.key = "story";
item2.type = "textarea";
item2.templateOptions = new TemplateOptions() { label = "Some sweet story", placeholder = "It allows you to build and maintain your forms with the ease of JavaScript :-)" };
m_fields.Add(item1);
m_fields.Add(item2);
retValue = JsonConvert.SerializeObject(m_fields);
return retValue;
}
The JSON result is:
[
{
"key":"text",
"type":"input",
"templateOptions":{
"label":"Text",
"placeholder":"Formly is terrific!"
}
},
{
"key":"story",
"type":"textarea",
"templateOptions":{
"label":"Some sweet story",
"placeholder":"It allows you to build and maintain your forms with the ease of JavaScript :-)"
}
}
]
Debugging with firebug i see the JSON passed correctly to the vm.fields but no input box is shown, only the Sumbit button.
I noticed that nor the Formly example shows the fields.
Can you help ?
Thanks in advance,
Giuseppe.
Here is a solution I've quickly hacked as a proof of concept for myself.
Basically the FormlyModelBuilder does scan a ViewModel class and builds a formly fields model.
Sample usage
public IActionResult Index()
{
return Ok(new ViewModels.Account.FormlyModelBuilder<ViewModels.Account.RegisterViewModel>().JsonStringify(new ViewModels.Account.RegisterViewModel { Email = "test#test.com" }));
}
Transforms this
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare ("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
into this
{
"fields": [{
"key": "Email",
"type": "email",
"templateOptions": {
"isRequired": false,
"label": "Email"
},
"expressionProperties": {
"templateOptions.focus": "Email"
}
}, {
"key": "Password",
"type": "password",
"templateOptions": {
"isRequired": false,
"label": "Password"
},
"expressionProperties": {}
}, {
"key": "ConfirmPassword",
"type": "password",
"templateOptions": {
"label": "Confirm password"
},
"expressionProperties": {}
}],
"model": {
"email": "test#test.com"
},
"expressionProperties": {}
}
Source Code
public class FormlyModelBuilder<T>
{
internal T GetAttributeFrom<T>(object instance, string propertyName) where T : Attribute
{
var property = instance.GetType().GetProperty(propertyName);
return GetAttributeFrom<T>(property);
}
internal T GetAttributeFrom<T>(PropertyInfo property) where T : Attribute
{
var attrType = typeof(T);
T t = (T)property.GetCustomAttributes(attrType, false).FirstOrDefault();
if (t == null)
{
var metaAttr = (MetadataTypeAttribute[])property.ReflectedType.GetCustomAttributes(typeof(MetadataTypeAttribute), true);
if (metaAttr.Length > 0)
{
foreach (MetadataTypeAttribute attr in metaAttr)
{
var subType = attr.MetadataClassType;
var pi = subType.GetField(property.Name);
if (pi != null)
{
t = (T)pi.GetCustomAttributes(attrType, false).FirstOrDefault();
return t;
}
}
}
}
else
{
return t;
}
return null;
}
internal FormlyModel<T> Build(T dataModel)
{
if (dataModel == null) throw new ArgumentNullException(nameof(dataModel));
//
var modelType = typeof(T);
var model = new FormlyModel<T>(dataModel);
foreach (var property in modelType.GetProperties(BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty | BindingFlags.Public))
{
var type = GetAttributeFrom<DataTypeAttribute>(property);
var field = new FormlyField(property.Name, GetInputTypeFromDataType(type?.DataType, property.PropertyType));
model.AddField(field);
//
var display = GetAttributeFrom<DisplayAttribute>(property);
field.TemplateOptions.Label = display?.Name;
//
var required = GetAttributeFrom<RequiredAttribute>(property);
field.TemplateOptions.IsRequired = required?.AllowEmptyStrings;
//
}
var focusField = model.Fields.First();
focusField.ExpressionProperties["templateOptions.focus"] = focusField.Key;
return model;
}
internal string JsonStringify(T dataModel)
{
if (dataModel == null) throw new ArgumentNullException(nameof(dataModel));
//
var dcr = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
dcr.DefaultMembersSearchFlags |= System.Reflection.BindingFlags.NonPublic;
//
return Newtonsoft.Json.JsonConvert.SerializeObject(Build(dataModel),
new Newtonsoft.Json.JsonSerializerSettings
{
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
ContractResolver = dcr
});
}
private string GetInputTypeFromDataType(DataType? dataType, Type propertyType)
{
if (dataType != null)
{
//
switch (dataType)
{
case DataType.Text:
return "input";
case DataType.Password:
return "password";
case DataType.EmailAddress:
return "email";
case DataType.Html:
case DataType.MultilineText:
case DataType.Custom:
case DataType.DateTime:
case DataType.Date:
case DataType.Time:
case DataType.Duration:
case DataType.PhoneNumber:
case DataType.Currency:
case DataType.Url:
case DataType.ImageUrl:
case DataType.CreditCard:
case DataType.PostalCode:
case DataType.Upload:
default:
break;
}
}
switch (propertyType.Name)
{
case nameof(System.Boolean):
return "checkbox";
default:
return "input";
}
}
}
internal class FormlyModel<T>
{
internal FormlyModel(T dataModel)
{
if (dataModel == null) throw new ArgumentNullException(nameof(dataModel));
//
this.Fields = new List<FormlyField>();
this.Model = dataModel;
this.ExpressionProperties = new Dictionary<string, string>();
}
internal IEnumerable<FormlyField> Fields { get; }
internal T Model { get; }
internal Dictionary<string, string> ExpressionProperties { get; }
internal void AddField(FormlyField field)
{
if (field == null) new ArgumentNullException(nameof(field));
//
((List<FormlyField>)this.Fields).Add(field);
}
}
internal class FormlyField
{
internal FormlyField(string key, string type)
{
if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key));
if (string.IsNullOrWhiteSpace(type)) throw new ArgumentNullException(nameof(type));
//
TemplateOptions = new TemplateOptions();
ExpressionProperties = new Dictionary<string, string>();
Key = key;
Type = type;
}
internal string Key { get; }
internal string Type { get; }
internal string HideExpression { get; set; }
internal TemplateOptions TemplateOptions { get; }
internal Dictionary<string, string> ExpressionProperties { get; }
}
internal class TemplateOptions
{
public bool? IsRequired { get; set; }
public string Label { get; set; }
public string Placeholder { get; set; }
}
Apparently, the version of Angular-Formly (6.0.0-beta.1) being used in the example is throwing exception. I remember this was working before. Any way I reverted it to a stable version and its working again.
Here is the jsbin with your formly json that is working as it should:
http://jsbin.com/towozegiqu/edit

Clearing system notification

I am trying to implement this plugin Phonegap system notification. I am reading two Rss feeds and displaying it to the user as a Status bar notification. Once the Notifications has been displayed to the user and the user clicks on the notification, he is taken to the app but I am not able to clear the notifications from the status bar. Could you please suggest me a way to clear these notifications by looking at my code.
How can I call navigator.systemNotification.cancelNotification() when the user clicks on the statusbar notification.
notification.js
google.load("feeds", "1");
google.setOnLoadCallback(function () {
var rss1old = '',
rss1new = '',
rss2old ='',
rss2new ='',
getRss = function (url, callback) {
(url) && (function (url) {
var feed = new google.feeds.Feed(url);
feed.load(function (result) {
(!result.error && callback) && (callback(result.feed.entries[0].title));
});
}(url));
};
setInterval(function () {
getRss(
'http://yofreesamples.com/category/free-coupons/feed/?type=rss',
function (title) {
rss1new = title;
if(rss1old !== rss1new) {
rss1old = rss1new;
navigator.systemNotification.onBackground();
navigator.systemNotification.updateNotification(rss1new,1);
navigator.notification.beep(1);
navigator.notification.vibrate(2000);
}
}
);
}, 5000);
setInterval(function () {
getRss(
'http://yofreesamples.com/category/real-freebies/feed/?type=rss',
function (title) {
rss2new = title;
if(rss2old !== rss2new) {
rss2old = rss2new;
navigator.systemNotification.onBackground();
navigator.systemNotification.updateNotification(rss2new,1);
navigator.notification.beep(1);
navigator.notification.vibrate(1000);
}
}
);
}, 6000);
});
SystemNotification.js -> Included from the plugin
function SystemNotification() {
}
SystemNotification.prototype.notificationEnabled = false;
SystemNotification.prototype.newCount = 0; //to keep track of multiple notifications events
SystemNotification.prototype.enableNotification = function () {
this.notificationEnabled = true;
};
SystemNotification.prototype.disableNotification = function () {
this.notificationEnabled = false;
};
SystemNotification.prototype.onBackground = function () {
this.enableNotification();
};
SystemNotification.prototype.onForeground = function () {
this.disableNotification();
};
SystemNotification.prototype.createStatusBarNotification = function (contentTitle, contentText, tickerText) {
PhoneGap.exec(null, null, "systemNotification", "createStatusBarNotification", [contentTitle, contentText, tickerText]);
};
SystemNotification.prototype.updateNotification = function (contentText, tickerText, number) {
this.newCount++;
var contentTitle = this.newCount + "RssFeeds";
if (this.newCount === 1) {
this.createStatusBarNotification(contentTitle, contentText, tickerText);
} else {
PhoneGap.exec(null, null, "systemNotification", "updateNotification", [contentTitle, contentText, this.newCount]);
this.showTickerText(tickerText); //optional
}
};
SystemNotification.prototype.cancelNotification = function (contentText) {
this.newCount--;
if (this.newCount === 0) {
PhoneGap.exec(null, null, "systemNotification", "cancelNotification", []);
}
else {
//updating the notification
var contentTitle = "my title";
PhoneGap.exec(null, null, "systemNotification", "updateNotification", [contentTitle, contentText, this.newCount]);
}
};
SystemNotification.prototype.showTickerText = function (tickerText) {
PhoneGap.exec(null, null, "systemNotification", "showTickerText", [tickerText]);
};
SystemNotification.prototype.touch = function () {
PhoneGap.exec(null, null, "systemNotification", "touch", []);
};
PhoneGap.addConstructor(function () {
if (typeof(navigator.systemNotification) == "undefined") {
navigator.systemNotification = new SystemNotification();
navigator.systemNotification.touch(); //this ensures that the plugin is added when phonegap kicks off
}
});
Systemnotification.Java -> Included from the plugin
package com.yfs.project;
import org.json.JSONArray;
import org.json.JSONException;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;
public class SystemNotification extends Plugin {
final int notif_ID = 1234;
NotificationManager notificationManager;
Notification note;
PendingIntent contentIntent;
#Override
public PluginResult execute(String action, JSONArray args, String callbackId)
{
PluginResult.Status status = PluginResult.Status.OK;
String result = "";
try {
if (action.equals("createStatusBarNotification")) {
this.createStatusBarNotification(args.getString(0), args.getString(1), args.getString(2));
}
else if (action.equals("updateNotification")) {
this.updateNotification(args.getString(0), args.getString(1), args.getInt(2));
}
else if (action.equals("cancelNotification")) {
this.cancelNotification();
}
else if (action.equals("showTickerText")) {
this.showTickerText(args.getString(0));
}
return new PluginResult(status, result);
} catch(JSONException e) {
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
}
}
private void updateNotification(String contentTitle, String contentText, int number)
{
note.setLatestEventInfo(this.ctx, contentTitle, contentText, contentIntent);
note.number = number;
notificationManager.notify(notif_ID,note);
}
private void createStatusBarNotification(String contentTitle, String contentText, String tickerText)
{
notificationManager = (NotificationManager) this.ctx.getSystemService(Context.NOTIFICATION_SERVICE);
note = new Notification(R.drawable.rss, tickerText, System.currentTimeMillis() );
//change the icon
Intent notificationIntent = new Intent(this.ctx, Yfs.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent = notificationIntent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
contentIntent = PendingIntent.getActivity(this.ctx, 0, notificationIntent, 0);
note.setLatestEventInfo(this.ctx, contentTitle, contentText, contentIntent);
note.number = 1; //Just created notification so number=1. Remove this line if you dont want numbers
notificationManager.notify(notif_ID,note);
}
private void cancelNotification()
{
notificationManager.cancel(notif_ID);
}
private void showTickerText(String tickerText)
{
note.tickerText = tickerText;
notificationManager.notify(notif_ID,note);
}
public void onPause()
{
super.webView.loadUrl("javascript:navigator.systemNotification.onBackground();");
}
public void onResume()
{
super.webView.loadUrl("javascript:navigator.systemNotification.onForeground();");
}
}
On android, you'll need to set the flag AUTO_CANCEL
Where you have this
note = new Notification(R.drawable.rss, tickerText, System.currentTimeMillis() );
Add this line right under
note.flags = Notification.FLAG_AUTO_CANCEL;

Categories

Resources