To set up dual monitor displays at Windows 10, right-click in the taskbar, pick "Properties" and then click "Customize..." and then from the "System" box that appears go to "Display" and start by changing "Multiple displays" to: "Extend desktop to this display" ...you know, I've kept this blog for 5+ years and only now am I using an operating system at work that is newer than the blog itself. (not Windows 7)
Tuesday, November 15, 2016
Monday, November 7, 2016
abstraction: the fourth pillar
I thought there were three pillars to OOO as suggested here. In Googling it some, it kinda seems like some lists include abstraction as a fourth pillar. In many ways this is a lot like encapsulation in that in both cases you are trying to expose what is important and marginally hide that which is merely necessary that should draw the eye less sort of like the distinction between the "Wizard" of Oz and the man behind the curtain. (We want to keep him behind a curtain.) However, that said, encapsulation is something in particular, very particular, and has to do with how gunk is kept in a class itself. Abstraction will have you pulling stuff out of a class to another class.
Addendum 2/22/2019: OOO stands for Out Of Office and really OOO here should be OOP for Object-oriented programming.
Use the ES6 fat arrow for simple function substitution.
var x = y => alert(y+y);
x("hi");
...which is gonna tell you "hihi" is bascially the same as...
var x = function(y){
alert(y+y);
};
x("hi");
There is a way to "autoseek" dependencies in web forms with StructureMap as one does in MVC where they may now auto-hydrate at controller constructors.
I spoke to someone who has done it before over a phone screen just now. It's nasty. You have to inject something into the HTTP model to catch a page before it complies code but after it's baked and inject stuff. Is ObjectFactory that evil that I should want to go there?
closures in JavaScript
What I suggest here is probably really wrong. Instead if you just Google against this topic you'll find stuff like this giving a different explanation. Alright, consider this:
var myClosure = function() {
counter++;
alert(counter);
};
myClosure();
myClosure();
myClosure();
It's gonna fail, right? You can't do plus plus on something undefined, right? Well, what if counter did correspond to a number in a backing store, someplace where state could be kept? It can. You can have this:
var myClosure = (function() {
var counter = 0;
return function() {
counter++;
alert(counter);
}
})();
myClosure();
myClosure();
myClosure();
This code will not break and will moreover throw up three alerts, one after the other, with 1, 2, and 3, in them. We have made counter a privately-scoped variable really only approachable by myClosure and we are using it as a backing store for state. After initial assignment, myClosure behaves in the code immediately above just as it does in the code at the very top of this blog posting. The only difference is that now counter means something.
Saturday, November 5, 2016
yet more RANDOM notes from trying to find a job
a lot of this is shamelessly stolen from other stuff I found online...
- var x = y.OrderByDescending(z =>
z.Date).ThenByDescending(z => z.Name).Skip(5).Take(8);
...is an example of .ThenByDescending/.Take/.Skip in a Lambdaland. - cookies are a long-standing way of maintaining state at the browser while sessionStorage and localStorage are new to HTML5. localStorage lasts until you get rid of it, cookies may be set to last X number of days or minutes, and sessionStorage only lasts until the browser closes
- data- attributes in HTML! You may invent your own "legitimate" inline parameter at an HTML tag to make it easy to latch onto the tag in JavaScript or communicate things in JavaScript.
- The Discovery web service is a tool used to determine the organizations that a user is a member of in Microsoft Dynamics CRM.
- Use both yield return and yield break TOGETHER...
while (true)
{
if (i < 5)
{
yield return i;
}
else
{
yield break;
}
i++;
}
super-simple example of using a directive at a custom tag in an AngularJS 1.5.8 application
Assuming the HTML at the top of this, let's place a new tag just inside the first div tag with the ng-app on it like so:
<add-Intro></add-Intro>
Alright, our directive itself looks like so:
app.directive("addIntro", function () {
return {
template: "Books by George R. Martin:"
};
});
Notice that the names don't match up one for one. You will have a directive name in camelCase and when you call to it with a tag in the markup then the names get hyphens between the words. Whatever. The copy in the template ends up painted to the screen at the tag's locale. Yippee! Anyways, if this seems like a pretty weak blog posting, it really is a wrap-up of a series of other blog postings. This is the sixth of six blog postings in which I build out an AngularJS app. I worked with Angular for like two weeks at @hand three years ago and of course I've forgotten it all so I've been trying to refresh myself. If you follow the following postings you could build out an app yourself!
I think it's neat that the first eight Roman numeral numbers come in alphabetic order, though I suppose that's off topic, eh? Anyways, I recommend just pulling Angular 1.5.8 from NuGet in Visual Studio and building out inside of the first web page your application surfaces when you run it. Add script tags for angular.min.js and angular-route.min.js. Hmmmm... I'm not sure I needed angular-route.min.js.
ng-class/ng-click, Array.isArray, and bolting your own properties onto API data for convenience sake
I've used ng-class and ng-click to make an expandable/collapsible menu in an AngularJS 1.5.8 application. Specifically, I have beefed up the HTML in the app I suggest here like so:
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="books in booksWrapper">
<div class="outerTemplateWrapper" ng-repeat="book in books">
{{ book.name }}
<div class="middleTemplateWrapper">
<div class="innerTemplateWrapper">
<div class="innerTemplateWrapperLeft">{{ book.isbn }}</div>
<div class="innerTemplateWrapperRight">
{{ book.numberOfPages|sOnTheEnd:"page" }}</div>
<div class="innerTemplateWrapperBase">
<div class="plusOrMinus" ng-class="book.toggleState ? 'plus' : 'minus'"
ng-click="characterCollector(book)"></div>
<div class="characters">characters</div>
<div class="secondInnerTemplateWrapperBase">
<ol ng-class="book.toggleState ? 'displayNone' : 'displayBlock'">
<li ng-repeat="hydratedCharacters in book.hydratedCharactersWrapper">
<span ng-repeat="hydratedCharacter in hydratedCharacters">
{{ hydratedCharacter.name }}
</span>
</li>
</ol>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
My controller has changed up some like so...
app.controller("myCtrl", function ($scope, apiGetter) {
var currentUrl = "http://www.anapioficeandfire.com/api/books";
$scope.booksWrapper = apiGetter.goGetIt(currentUrl).$$state;
$scope.characterCollector = function (book) {
book.toggleState = !book.toggleState;
if (!book.hasHydratedCharacters) {
book.hasHydratedCharacters = true;
var counter = 0;
book.characters.forEach(function (characterUrl) {
if (counter < 10) {
var character = apiGetter.goGetIt(characterUrl).$$state;
book.hydratedCharactersWrapper.push(character);
}
counter++;
});
}
};
});
So it's still getting data upfront for a list of Game of Thrones books and now it is also fishing for new data. The API doesn't include characters for the books with the books, instead it has a list of URLs to hit to make API calls for each character and... well... let's get the first ten characters for each book. The service I made for the API calls is going to change too:
app.service("apiGetter", function ($http) {
return ({
goGetIt: goGetIt
});
function goGetIt(whereToLookTo) {
var request = $http({
method: "get",
url: whereToLookTo
});
return (request.then(handleSuccess, handleError));
}
function handleError(response) {
alert('something went wrong');
}
function handleSuccess(response) {
if (!Array.isArray(response.data)) {
return (response.data);
} else {
var dataPlus = new Array();
response.data.forEach(function (book) {
book.toggleState = true;
book.hasHydratedCharacters = false;
book.hydratedCharactersWrapper = new Array();
dataPlus.push(book);
});
return (dataPlus);
}
}
});
Basically, for the array of books that comes back upfront I want to bolt on my own properties per book, but for the characters themselves, I just want to hand them back as is. The three properties I bolt onto each book are an empty array for eventually later spooling up the characters in and two flags for if that array has been hydrated yet (we don't want to do it over and over) and if an expandable/collapsible menu for showing the array's contents is sitting open. Some CSS is driven by the later flag. It looks like this:
.plus:before {
content: "+";
}
.minus:before {
content: "-";
}
.displayNone {
display: none;
}
.displayBlock {
display: block;
}
Every div with the plusOrMinus class on it, containing cursor: pointer; as a style by the way, is now a button! Clicking the button will change a plus sign to a minus sign or a minus sign to a plus sign based upon the flag for this state. It will also hide or unhide an ordered list in another div which has the list of characters!
an excuse to use a filter in an AngularJS 1.5.8 app
A coworker once showed me an example of a filter that he wrote which pluralized some (a majority) of English words correctly. I'm ripping off his idea here:
app.filter("sOnTheEnd", function () {
return function (number, word) {
if (word === undefined) {
return number;
}
var pattern = number + " " + word;
if (number == 1) {
return pattern;
} else {
return pattern + "s";
}
};
});
I call out to it with the double curly braces syntax like so:
{{ book.numberOfPages|sOnTheEnd:"page" }}
You will note that I've baked in some extra love to keep "undefineds" from showing up in the HTML when this is attempted:
{{ book.numberOfPages|sOnTheEnd }}
Get data from a $http AJAX call into $scope and then into an ng-repeat in an AngularJS 1.5.8 app.
I struggled with this some this morning. The trick is to have a loop inside a loop like so:
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="books in booksWrapper">
<div class="outerTemplateWrapper" ng-repeat="book in books">
{{ book.name }}
</div>
</div>
</div>
I'm using the same service I suggest here for $http although my controller has changed up some. It now looks like this:
app.controller("myCtrl", function ($scope, apiGetter) {
var currentUrl = "http://www.anapioficeandfire.com/api/books";
$scope.booksWrapper = apiGetter.goGetIt(currentUrl).$$state;
});
That looks plain as day, right? And you wouldn't think I'd need a loop inside of a loop, right? Why the nesting? Well, if you just have one loop you will notice two placeholders appear in the HTML (try to repeat divs or Xs or something) and the second of the two will appear a bit after the first. I suspected the second item was the results coming back from the API asynchronously. At first I had the usual I-hate-the-asynchronous anger of a C# developer and longed to find a way to delay until the second item came back and to isolate it and assign that to scope, but that wouldn't have been terribly mature on my part, huh? The better thing to do is to just build something that accommodates an object with a first property to ignore and a second property to coddle and care about (kinda like how a dad only loves his second son in both Gattaca and Filth). It's easy when only the second property is an array as only the second property can fill out a second loop. If you throw $scope.booksWrapper to the console in myCtrl, you can see the two things on it. In Google Chrome's console, the first is immediately there and the second comes in when it can.
- Object
- status: 1
- value: Array[10]
- __proto__: Object
Bonus: I never could figure out how to get at the snipping tool in Windows 8, though I sort assumed it was there. I found it in Windows 10 this morning. Just type "snip" at that thing at the lower left which says: "Ask me anything"
Friday, November 4, 2016
How to make an API call in an AngularJS 1.5.8 application.
Alright, starting with the very simple application I suggest here, I am going to revamp my token controller from:
app.controller("myCtrl", function ($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
...to...
app.controller("myCtrl", function ($scope, apiGetter) {
$scope.currentUrl = "http://www.anapioficeandfire.com/api/books";
var content = apiGetter.goGetIt($scope.currentUrl);
console.log(content);
});
I bet you can kinda tell what the revamped myCtrl is gonna to do, right? It's gonna hit the http://www.anapioficeandfire.com/api/books endpoint and barf what it collects from it up to the console. It is going to use apiGetter to do its magic, right? What is that. That's a service. I followed this for that! It appears you may just list the names of services you want in scope in a controller as variables in the function signature for the controller. My service looks like this:
app.service("apiGetter", function ($http) {
return ({
goGetIt: goGetIt
});
function goGetIt(whereToLookTo) {
var request = $http({
method: "get",
url: whereToLookTo
});
return (request.then(handleSuccess, handleError));
}
function handleError(response) {
alert('something went wrong');
}
function handleSuccess(response) {
return (response.data);
}
});
The last of the links I give suggests the three functions are "methods" and makes a distiniction between public and private methods. The goGetIt method is made public by way of being on the object in the return above all the methods. You could have many comma-seperated methods as properties here if you need more than one. It took me a while to realize that I needed to add goGetIt to what is returned in order for myCtrl to be able to use it dotting off of apiGetter. That is what makes it "public" so to speak.
A friend gave me an Angular2 app just now.
I was told to navigate to where I unpackaged it from its tarball to at the command prompt and to then type npm install followed by npm start. The second command actually brings the app up in a browser. Both commands worked. I typically have no luck at all with the npm stuff on my PC laptop, but this time it behaved. Nothing broke. Under the root of the project there is a "node_modules" folder and within that there is an "angular2" folder.
Thursday, November 3, 2016
SparkHire
...is an interesting tool for recording videos of applicants being interviewed by canned, pre-defined questions. I had an interview over SparkHire against ten generic ASP.NET questions and it was pretty slick. I could think about a question for X minutes, then have X minutes to record a video of myself answering. There could be X number of takes and I could review a take before approving it. The Xs are all set as variables by whoever preps the interview.
Make a Razor ActionLink open the link's URL up in a new tab.
@Html.ActionLink("touch me", "Index", "Home", null, new { target = "_blank" })
do NOT do this instead...
@Html.ActionLink("touch me", "Index", "Home", new { target = "_blank" })
...as this will make ?Length=4 appear at the end of the URL at the new tab.
some notes from trying to get an Angular app up and running
- install-package AngularJS at the NuGet command prompt installs AngularJS 1.5.8
- https://github.com/mgechev/angular-seed is an Angular2 seed project
- http://markdownpad.com/ is a Markdown editor for Windows and you should be able to read a README.md with it
- Yarn is a tool for caching locally downloaded dependencies
- Install-Package angular2.TypeScript.DefinitelyTyped will install some Angular2 scripts, including TypeScript, at a Visual Studio project but it will loops in TypeScript which cannot compile in alpha files
- http://blogs.msmvps.com/ was recommended as a good resource
- There is no way to upgrade from Angular 1 to Angular 2. The circumstance demands a rewrite.
- Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.5.8/$injector/modulerr?p0=myApp&p1=Error%3A%2…Bc%20(http%3A%2F%2Flocalhost%3A56663%2FScripts%2Fangular.min.js%3A21%3A179)(…) is the error I get in Google Chrome's console when I try to loop in angular.min.js in a AngularJS 1.5.8 app in Visual Studio 2015. Of course there is no way to Google against this error message which is one of the toughest things about Angular. Wait! That's only if a decorate a div with ng-app="myApp" so I'm probably missing a definition.
- var app = angular.module("myApp", []); ...fixes the problem above and this is perhaps a good cheatsheet
- per the cheatsheet <div ng-app="myApp" ng-controller="myCtrl"> will also loop in a controller and there example is:
app.controller("myCtrl", function ($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
RUP is Rational Unified Process methodology
This feels like a process halfway between Agile and Waterfall in which there are four phases (Inception, Elaboration, Construction, Transition) making the development technically iterative, but not nearly as minutely so as Scrum. Also there are fixed deadlines to hit (specific dates). Well... why not? There are no Agile purists anymore so who is to say this is bad? Everyone (every business) just does their own thing anyways.
Wednesday, November 2, 2016
ROW_NUMBER in T-SQL is another thing I keep botching in interviews. (twice now)
The interview challenge: How do you return a page of "pagination" more than one page deep in T-SQL results? Well, if it's just the first page, that's easy right? You do something like what follows, to use the Problems table I made here as an example.
SELECT TOP(10) * FROM Problems
WHERE PersonId != 4
ORDER BY ProblemId
But if we want a different "page" ...then what. I had this in my notes, but I suspected it was really expensive (and I still think that) and as a result I found this online which offered:
SELECT * FROM
(
SELECT ROW_NUMBER() OVER ( ORDER BY ProblemId ) AS Spot,
* FROM Problems
WHERE PersonId != 4
) AS WhateverYoudLikeHere
WHERE Spot >= 11 AND Spot <= 20
ORDER BY ProblemId
Tuesday, November 1, 2016
some assorted notes from a set of recent interviews
- You may visit http://www.anapioficeandfire.com/api/books plain as day in a browser, but if you try to slurp the JSON object there down into some jQuery AJAX at an .html page on your desktop that you are just running through Google Chrome you may be in for some heartache. In looking a Fiddler, you see the call consumed successfully and yet the in-page .ajax call falls over to it's error method. Why so? Partway into this is this copy: Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, but they're limited by the same origin policy. Extensions aren't so limited. An extension can talk to remote servers outside of its origin, as long as it first requests cross-origin permissions. Ah-ha! That has half of the answer for what to do and the rest may be found here, and yes there is a solution. It's not that the thing you are consuming needs to open up CORS permissions, but instead it does actually have something to do with you. Open the command prompt as administrator and navigate to where Chrome lives. On my laptop that is at: C:\Program Files (x86)\Google\Chrome\Application ...then run this command: chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security ...to get a version of Google Chrome with watered-down security. Remember, it worked in Fiddler. It's just Chrome itself that is cantankerous. There is a second step and that is to use async:false/crossDomain:true/dataType:'json' like so:
$.ajax({
url: 'http://www.anapioficeandfire.com/api/books',
type: "GET",
async: false,
crossDomain: true,
dataType: 'json',
success: function(result) { console.log(result); alert('Success'); },
error: function(result) { alert('Failed!'); }
}); - jsbin.com is an interesting place to build and test JavaScript.
- A C# using statement is not taking a try/catch/finally shape in CLR. It has a try/finally vibe. If an exception is thrown in the try part, the finally part still runs (the Dispose method for the IDisposable implementation) but the exception is not caught and "handled." It bubbles right up to you!
- There is a .hasClass in jQuery that goes with the .addClass and .removeClass stuff.
- A gist at GitHub allows for you to save and share a code snippet without dedicating a repository to as much.
- Yes, internal classes may be seen outside of their immediate project in a C# solution by creating a friend relationship between two assemblies.
- The memory leak in Angular's two-way data binding has been significantly improved between version 1.3 and version 1.5.8.
- Try to always use the strictly equals in JavaScript comparisons as the == operator might allow for 6 and "6" to be equal and hence allow for code to blow up downstream.
Monday, October 31, 2016
Make an HttpContent child for an HttpClient and add a header too.
I wanted to do something like this, but it took a bit of a different shape...
using System;
using System.Net.Http;
using System.Text;
using System.Web.Mvc;
using System.Web.Script.Serialization;
namespace HPS.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
using (var client = new HttpClient())
{
var package = new { Foo = "bar", Baz = "qux" };
JavaScriptSerializer serializer = new JavaScriptSerializer();
var json = serializer.Serialize(package);
Uri uri = new Uri("http://www.example.com/api/toucheme/");
var content = new StringContent(json, Encoding.UTF8, "application/json");
content.Headers.Add("X-EXTRA", "whatever");
var response = client.PostAsync(uri, content).Result;
}
return View();
}
}
}
Note that the second parameter for the .PostAsync is an HttpContent and you cannot just new one of these up. It's an abstract class and you need an actor that inherits from it. In the case of the StringContent (our actor) I recommend having all three parameters I specify to avoid 415 (unsupported media type) errors.
Sunday, October 30, 2016
old school generic connection string
"Data Source=cloudland.paradise.example.com;Initial Catalog=SummerWind;Persist
Security Info=True;User ID=jblow;Password=letmein"
Saturday, October 29, 2016
TechSmith Camtasia
...is software for capturing your screen as you work on code. It will record audio and video. You may present to an audience at a tech talk and record your tech talk.
Friday, October 28, 2016
How do I know that the ViewState has not been tampered with?
This line of copy at the top of a web form's aspx markup is called an @Page directive:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"
Inherits="Damisam.UserInterface.Default" %>
...and putting EnableViewstateMac="true" inline here ensures that the ViewState has not been tampered with form-submission-to-form-submission.
window.onload
JavaScript's window.onload will occur after all the content on a page, images and all, has finished loading while jQuery's $(document).ready() happens when just the HTML is done loading. Use window.onload like so:
window.onload = function() {
alert('whatever');
};
Material Design for Bootstrap
A good question to ask when someone is telling you about their ASP.NET MVC application is "How do you make paginated lists?" because the answer probably has to do with something more than just .ToPagedList. There is probably a third party control library of some sort such as DevExpress. Material Design for Bootstrap is one of them. Some links:
Thursday, October 27, 2016
Did you know there is an OnException action filter in MVC?
It's a lot like the OnAuthorization action filter...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Something.Models;
namespace Something.Controllers
{
public class HomeController : Controller
{
protected override void OnAuthorization(AuthorizationContext filterContext)
{
//whatever
}
protected override void OnException(ExceptionContext filterContext)
{
//whatever
}
...and these four characters. It's one of the six filtering methods one may use at a controller.
DbUnit is used with JUnit in the Java space.
It's for making dummy objects for your unit tests to muck with.
I just screwed up the world's easiest interview question so I guess that merits a blog posting.
What is the difference between outer and inner joins? My answer: The main table to which another table is joined may return numerous rows for the "joined-in" data for every row it returns in an outer join, but in an inner join there is a strict one-to-one relationship.
Wrong. This is not so. In both cases the main table to which another table is joined may return numerous rows for the "joined-in" data for every row it returns, however it's best, and perhaps a little counterintuitive, to think of the "joined-in" table as in the driver's seat. All of the records will be returned from the joined table except for those for which there is not a match in the main table, and if the join happens on a foreign key restraint relationship where a child is joined up to a parent then forget the "except" part of what I say altogether leaving: All of the records will be returned from the joined table. So what is the difference between outer and inner joins? If the main table has records which do not have a dance partner in the joined table these records will appear in outer joins and will not appear in inner joins. In these records the columns that come back for the joined table data points in the record set the query coughs up will just have null values.
Addendum 10/31/2016: What I say above about only one record per record for the joined table above really isn't true, certainly not if you join a parent to a child. The thing to really remember is that an inner join shows just the records where both tables have data while a left join will also show the main table's data even if there is not corresponding data in the joined table for a row returned.
Wednesday, October 26, 2016
LINQ ABCs
Having learned C# 2.0 first, for the longest time I just wrote foreach loops and would let ReSharper refactor them into LINQ or Lambda shapes. More recently, I've gotten pretty confident in writing Lambda expressions. LINQ seems to come up for less simplistic refactorings, but I was looking over this on Monday and it's really not rocket science. If you can write T-SQL you can write LINQ. It sure feels similar. Observe:
var whatever | = | from person in people select person; |
Obviously, what's above is a simple select. If we have an IEnumerable or List of Person in people then we would comically be just getting an IEnumerable of the same stuff. Clearly we need to filter. We do that like so, and again this is gonna look a lot like T-SQL...
var whatever | = | from person in people where person.FirstName == "Clive" select person; |
Use double ampersands or double pipe symbols in the where clauses for and/or logic in filtering Clive records. Order the Clives like so:
var whatever | = | from person in people where person.FirstName == "Clive" orderby person.LastName descending select person; |
The let keyword is for a midstream transformation!
var whatever | = | from person in people let maybedutches = person.LastName.Split(' ') from maybedutch in maybedutches where maybedutch == "Van" select person; |
I had heard that joins are pretty painful in Entity Framework and since the selects are all LINQ statements I can see why! Look at this:
var whatever | = | from person in people join phone in phones on phone.Number equals person.Phone select new { Name = person.FirstName, Country = phone.Country }; |
Well yuck, anonymous types! Yeesh! The first link I provide also goes into some esoteric groupings. Basically you can break a collection into a collection of collections all sorted out by something-er-other. You end up with an IEnumerable<IGrouping<string, Person>> which is straying beyond that which is common and simple.
Tuesday, October 25, 2016
what you can and cannot do with Session and Html.RenderAction
What if this controller...
using System;
using System.Web.Mvc;
namespace Something.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
Session["state"] = 0;
return View();
}
public ActionResult Yin()
{
int state = Convert.ToInt32(Session["state"] as string);
state = state - 1;
Session["state"] = state;
return PartialView("_Yin", state);
}
public ActionResult Yang()
{
int state = Convert.ToInt32(Session["state"] as string);
state = state + 1;
Session["state"] = state;
return PartialView("_Yang", state);
}
}
}
...coughed up this action?
@{
Layout = null;
}
<html>
<head>
<script type="text/javascript" src="~/Scripts/jquery-1.10.2.min.js"></script>
</head>
<body>
<div>
<button id="yinbutton">yin</button>
<div id="yin">
@{
Html.RenderAction("Yin");
}
</div>
<button id="yangbutton">yang</button>
<div id="yang">
@{
Html.RenderAction("Yang");
}
</div>
</div>
<script type="text/javascript">
$('#yinbutton').bind('click', function () {
var route = '@Url.Action("Yin", "Home", new {})';
$.ajax({
url: route,
type: "GET"
}).done(function (partialViewResult) {
$("#yin").html(partialViewResult);
});
});
$('#yangbutton').bind('click', function () {
var route = '@Url.Action("Yang", "Home", new {})';
$.ajax({
url: route,
type: "GET"
}).done(function (partialViewResult) {
$("#yang").html(partialViewResult);
});
});
</script>
</body>
</html>
Let's also have these two partial views in the mix.
- _Yin.cshtml:
@model int
<div>Partial One: @Model.ToString()</div>
- _Yang.cshtml:
@model int
<div>Partial Two: @Model.ToString()</div>
I had a hunch here that state could not be communicated between partials with Session, but this is only partially true. Observe what happens when we run our code.
What is above shows what happens both when the view spins up and when either of the buttons is clicked. The buttons should increment the number kept in Session up and down, but they do nothing. However, I should stress that if nothing else, at least the zero set upfront is communicated out to the partials. It just seems the partials lack the "page lifecycle" (forgive the web forms analogy) to set something in Session. What if we use the cache instead?
using System;
using System.Runtime.Caching;
using System.Web.Mvc;
namespace Something.Controllers
{
public class HomeController : Controller
{
private static ObjectCache _objectCache
{
get { return MemoryCache.Default; }
}
public ActionResult Index()
{
CacheItemPolicy cacheItemPolicy = new CacheItemPolicy();
_objectCache.Add(new CacheItem("state", 0), cacheItemPolicy);
return View();
}
public ActionResult Yin()
{
int state = Convert.ToInt32(_objectCache["state"]);
_objectCache.Remove("state");
state = state - 1;
CacheItemPolicy cacheItemPolicy = new CacheItemPolicy();
_objectCache.Add(new CacheItem("state", state), cacheItemPolicy);
return PartialView("_Yin", state);
}
public ActionResult Yang()
{
int state = Convert.ToInt32(_objectCache["state"]);
_objectCache.Remove("state");
state = state + 1;
CacheItemPolicy cacheItemPolicy = new CacheItemPolicy();
_objectCache.Add(new CacheItem("state", state), cacheItemPolicy);
return PartialView("_Yang", state);
}
}
}
What is below is given upon the spin up initially before any of the buttons are clicked. We can see that the original zero value may not only be communicated outward, but may also be updated!
The two buttons work too! They will move the number in the cache up and down and communicate that up to the UI by way of an AJAX refresh of some HTML.
browserLink/requestData error at the console with Visual Studio 2013
To get rid of this, right-click on the icon of a circluar arrow bending back on itself in a loop that is just to the right of the option with a green arrow for previewing your code in a browser with the debugger (should be the only button with a rightward pointing green triangle) and then toggle "Enable Browser Link" to stop this.
Sunday, October 23, 2016
ITT Technical Institute loses accreditation!
I just ran into a friend who has an associates degree from ITT Tech and now that degree is worthless. He is going to start a legal process to wiggle away from his student debt which was accrued for not. What a gut punch. ITT used to stand for International Telephone and Telegraph so they must have been around for forever. Now they are gone.
Abstraction is a technique for arranging complexity.
I know that's vague. (It's what Wikipedia says.) It's teasing two concerns apart and letting them touch through modest isolation from each other. An abstract class in C# has some extra methods that the thing inheriting from it gets to use, etc. This as opposed to having one big fat class with no inheritance break out. That which gets abstracted out in this case could be repurposed by a second child.
Friday, October 21, 2016
Twitter, Netflix, Ello, and Reddit were all taken offline today by way of some manner of DNS poisoning.
It's the biggest DDoS attack I've seen. What was the point of this? Was this just a test of taking the internet down? Does the "real" attack come later? Who is behind it?
Thursday, October 20, 2016
OnResultExecuting and OnResultExecuted
These ASP.NET MVC events happen in this order:
- OnActionExecuting
- OnActionExecuted
- OnResultExecuting
- OnResultExecuted
OnResultExecuting and OnResultExecuted are for coughing up the view after the Action is done with its handover.
some notes on Entity Framework
The code first approach comes with some troubles. A DBA cannot just add a column at a table and expect that to be matched by a developer adding a corresponding getsetter on a POCO. The change has to be hydrated to the database from the code. Data Migrations with Code First expect a very specific configuration and are otherwise sabotaged if code first is not indeed, code first. Code first and the "read from schema" .edmx thing are BOTH bad as it turns out, but we are not stuck with just two bad choices as it turns out. There is another approach called Reverse Engineering Code First which creates classes off an existing schema. You should not, with this approach, start with Code First and then generate a second code base off of drinking up the database tables as the two code bases will be different. You need to start with the database. I was told all this verbally yesterday and I also learned that the hydrated code from the database all ends up in one folder and that that folder may just be destroyed and rerendered when the schema changes. When my mind attempts to picture this it also pictures that that which I would put in the Infrastructure and that which I would put in the Core in an Onion Architecture to be sprinkled about in the same folder together. Maybe the third choice has a dark side?
pseudoSQL inside NHibernate
You break into HQL when you admit the ORM ain't all that and HQL stands for Hibernate Query Language. The problem is that it's not quite SQL and you have to learn this other, goofy thing.
Wednesday, October 19, 2016
Who are the gang of four?
They are the authors of "Design Patterns: Elements of Reusable Object-Oriented Software"
- Eric Gamma
- Richard Helm
- Ralph Johnson
- John Vlissides
Robert Cecil "Uncle Bob" Martin and Martin Fowler on not on the list. I just made this mistake in an interview. :(
casting fails!
Consider the following C# classes:
- namespace Something.Models
{
public class Cat
{
public int Lives { get; set; }
public Cat()
{
Lives = 9;
}
}
}
- namespace Something.Models
{
public class BakersCat : Cat
{
public BakersCat()
{
Lives = 13;
}
}
}
- using Something.Models;
namespace Something.Utilities
{
public static class Killer
{
public static Cat Kill(Cat cat)
{
cat.Lives = cat.Lives - 1;
return cat;
}
public static void Kill(ref Cat cat)
{
cat.Lives = cat.Lives - 1;
}
}
}
Well this won't work...
BakersCat muffin = new BakersCat();
muffin = Killer.Kill(muffin);
...and this won't work either!
BakersCat cookie = new BakersCat();
Killer.Kill(ref cookie);
Tuesday, October 18, 2016
XSL stands for eXtensible Stylesheet Language
...and XSLT and XSL-FO are the two varieties. I had not heard of XSL-FO before today. It seems to be the markup that is under the hood in an Adobe Acrobat PDF (Portable Document Format) file.
.NET 3.0 came out of the box with Visual Studio 2008.
You had to install an update to get .NET 3.5 which unlocked C# 3.0 and the LINQ (Language Integrated Query) and Lambda stuff that came with it. C# 2.0 and C# 3.0 used the same runtime engine and basically the 3.0 stuff gave you different things to compile to CLR without any of the CLR itself being new.
Monday, October 17, 2016
Merge Sort Algorithms
I just read this and found it interesting. I'm intrigued by the O(n²) challenge of a loop running inside a loop and how to optimize it. One suggestion, which will NOT fit every case, may be to break that which is being crawled up into chunks. If there are sixteen items to crawl and sixteen squared is two hundred fifty-six, then if we broke the sixteen up into four fours and four squared is just sixteen again and sixteen times four is just sixty-four, then we are starting off in a better place than with two hundred fifty-six. When we cross-compare our four chunks I guess we have to do it wisely, but hopefully the optimization keeps us from climbing as high as two-hundred fifty-six, etc.
.SingleOrDefault
...in LINQ is a lot like .FirstOrDefault. If you are familiar with .FirstOrDefault you can probably guess what .SingleOrDefault does, huh?
- It will return the default value for the type if there are no matches.
- It will return what it finds if there is one match.
- It will throw an exception if there is more than one match.
You can have two columns with the same name come back in a T-SQL select.
...but it can't be healthy.
struct copies in C#
A struct, when copied, will carry into the new copy new value types such an int and DateTime and clearly changing these at one copy does not alter them at the other copy... but what about reference types for pointers? If it's a string, there will be a new string at the copy with a new pointer and changing one string does not affect the other, but if it's a class, the two structs will both have pointers to the same spot on the heap for the class. If you use structs instead of classes as your secondary actors then you cannot change up the getsetters on them after the fact, you to new up a new secondary struct to make a change to a copy of a class clinging to it at a property. The same trick obviously can be done to get around dupe pointer problems with classes.
There is such a thing a nullable value types in C#!
There is a mut keyword one may use in structs to bring in mutability. It's hacky.
A screen door on a stored procedure is not as silly as a screen door on a submarine.
Instead of having one sproc which gets a bunch of cats by int key and another that gets the cats by varchar special name identifier, it is best if there is one sproc with some complicated front door logic (if not null for one, then find the other) to keep the sprocs from being copied into two places and requiring logic that trickily will need maintenance in two places when the Cat table gets a new column. Meow!
Resolve Conflict
Going to: Resolve > Resolve Conflict ...tends not to actually clean up the mine/theirs in code and instead just marks a file as resolved so you may check it back into source control without source control complaining. Be careful with this.
else if!
namespace Something.Something
{
public static class Whatever
{
public static int GetNumber(bool? foo)
{
int bar = 13;
if (foo == null)
{
bar = 42;
}
else if (foo == true)
{
bar = 69;
}
else
{
bar = 86;
}
return bar;
}
}
}
protected override
Consider:
using AutoMapper;
namespace Payme.Whatever
{
public class FooMapping : Profile
{
public override string ProfileName => GetType.Name;
protected override void Configure()
{
Mapper.CreateMap<Foo, Bar>();
}
}
}
Random thoughts on this...
- I'm not sure what setting the Profile name in AutoMapper's way of doing things gets us.
- protected override is a thing. Think IDisposable.
- This may or may not be a Liskov violation. It depends on the intent of "contract" and would be changes.
- If you do your own thing in an IDisposable pattern and then call base.Dispose() it's not a violation.
- This may or may not be a Liskov violation. It depends on the intent of "contract" and would be changes.
how to make a field in a DevExpress MVC grid a link
settings.Columns.Add(m => m.Name, column =>
{
column.SetDataItemTemplateContent(content =>
{
ViewContext.Writer.Write(
Html.ActionLink(Context.Text, "Action", "Controller", new { foo =
DataBinder.Eval(content.DataItem, "Name")}, null).ToHtmlString()
);
});
});
Yes, you have to have that null. Trust me.
Sunday, October 16, 2016
how to conditionally hide a DevExpress grid if the model bound (a collection) has no records BUT NOT WHEN FILTERING ROWS HIDES ALL ROWS
We need something like this, but more complicated, and so...
s.SetVisible ( s.GetVisibleRowsOnPage() > 0 );
...should be replaced with handing s into a more complicated function.
function MaybeHide(s) {
if(s.GetVisibleRowsOnPage() > 0) {
s.SetVisible(true);
} else {
var actors = $('input[type=text]').toArray();
var isFiltering = false;
for (var i=0; i < actors.length; i++) {
if(i !=0 && i != (actors.length-1)){
if (actors[i].value) {
isFiltering=true;
}
}
}
if(!isFiltering) {
s.SetVisible(false);
}
}
}
Above:
- for (var i=0; i < actors.length; i++) { checks to see if a field for filtering is doing its thing, but not every field. We are making some assumptions and only checking to see if the fields which are not the first and last field have copy in them. The last field is likely the pagination drop down. The first field in this example? Oh, perhaps a different control elsewhere on the page. This has to be set on a case-by-case basis. Tailor it to your stuff!
- if (actors[i].value) { is going to be falsey if the filter field is empty and truthy otherwise. Get it?
The Ankh way of cleaning up conflicts in Visual Studio is a lot cleaner than figuring out the mine/theirs stuff which it kinda hides from you.
- Go to: View > Other Windows > Pending Changes
- Find an applicable line item here and pick "Edit Conflicts" after right-clicking upon it.
- Check checkboxes.
- Click "Accept Merge" at the upper right.
- Once more find your line item, right-click upon it and pick: Resolve > Resolve Conflict
how to conditionally hide a DevExpress grid if the model bound (a collection) has no records
settings.ClientVisible = Model.Any();
settings.ClientSideEvents.EndCallback = "function(s,e) { s.SetVisible (
s.GetVisibleRowsOnPage() > 0 ); }";
It is probably wise to have nullable ints instead of ints at signatures for actions driving partials.
This makes them less error prone. If they are called without a value being handed in they will not squawk an exception.
Use the "Network" tab under the F12 tools in Google Chrome to see if a controller action is even being hit. It will show traffic.
- Uncaught TypeError: Cannot read property 'validator' of undefined
- Uncaught TypeError: $ is not a function
These errors appear in the console of Google Chrome if jQuery's script tag doesn't come before the script tags for DevExpress. The DXR.axd will be mentioned. jQuery's script tag really needs to go at the top of the page and not in the footer.
State maintenance in the MVC DevExpress paradigm is super painful!
The how to for communicating records from a view to a partial across a callback refresh in the DevExpress paradigm is tricky. You cannot use a backing store in the traditional sense (a field or a getsetter) which basically means you are left with:
- putting things in the cache
- or serializing types to strings, letting strings travel from C# into JavaScript and then back to C# and then deserializing
In the first approach, you will use a magic string (maybe a GUID) for a key to a bit of the cache that should expire in fifteen minutes (strongly recommend, and I mean the cache contents should expire not the GUID, mkay?) and that magic string will, like serialized gunk, go from C# to JavaScript and back to C#. You can also go to the database every time you reload a partial to rehydrate obviously if you want to forgo lingering state conceptually altogether. It's up to you as to if that makes sense. I assume you cannot just use Session. I've had the worst AJAX experiences with Session.
Addendum 10/25/2016: You can somewhat use Session, in a sickly way. See: this
another generic example of a DevExpress MVC GridView with a lot of the functionality wired up
@{
Html.DevExpress().GridView<Foo>(
settings =>
{
settings.Columns.Add(m => m.Bar, column =>
{
column.Width = Unit.Percentage(25);
});
settings.Name = "Whatever";
settings.Styles.Header.CssClass = "myHeader";
settings.Styles.PagerBottomPanel.CssClass = "gridPager";
settings.Styles.AlternatingRow.CssClass = "meh";
settings.Settings.ShowFilterRow = true;
settings.Settings.ShowFilterRowMenu = true;
settings.Settings.AutoFilterCondition = AutoFilterCondition.Contains;
settings.SettingsBehavior.AllowGroup = false;
settings.SettingsBehavior.AllowSort = false;
settings.SettingsPager.AlwaysShowPager = true;
settings.SettingsPager.PageSizeItemSettings.Visible = true;
settings.SettingsAdaptivity.AdaptivityMode =
GridViewAdaptivityMode.HideDataCells;
settings.SettingsAdaptivity.AllowOnlyOneAdaptiveDetailExpanded = true;
settings.EditFormLayoutProperties.SettingsAdaptivity.AdaptivityMode =
FormLayoutAdaptivityMode.SingleColumnWindowLimit;
settings.EditFormLayoutProperties.SettingsAdaptivity
.SwitchToSingleColumnAtWindowInnerWidth = 600;
settings.SettingsPager.PagerSizeItemSettings.Items = new string[] { "10", "25",
"50" };
}
).Bind(Model).GetHtml();
}
A few things about this:
- This markup really needs to go in a partial all by itself. It's OK if there is some other Razor markup in there to loop in a List of Foo as the Model for example, but there cannot be another bit of markup in the partial which makes other HTML that sits side by side with our princess as otherwise princess will misbehave.
- That which is in yellow is our List of Foo.
- That which is in purple is a needed note to suggest that in contrast to what the collection might be hydrating the whole list, an individual line item is of Foo. Doesn't this seem silly? It sure does to me. It seems like DevExpress could just figure this out for you. It makes me think of .min.js.map, but I digress.
- That which is in purple must be there in order for that which is in teal to work.
- That which is in white may be crafted in an alternative way as shown below. Choose wisely.
@(
Html.DevExpress().GridView<Foo>(
settings =>
{
settings.Columns.Add(m => m.Bar, column =>
{
column.Width = Unit.Percentage(25);
});
settings.Name = "Whatever";
settings.Styles.Header.CssClass = "myHeader";
settings.Styles.PagerBottomPanel.CssClass = "gridPager";
settings.Styles.AlternatingRow.CssClass = "meh";
settings.Settings.ShowFilterRow = true;
settings.Settings.ShowFilterRowMenu = true;
settings.Settings.AutoFilterCondition = AutoFilterCondition.Contains;
settings.SettingsBehavior.AllowGroup = false;
settings.SettingsBehavior.AllowSort = false;
settings.SettingsPager.AlwaysShowPager = true;
settings.SettingsPager.PageSizeItemSettings.Visible = true;
settings.SettingsAdaptivity.AdaptivityMode =
GridViewAdaptivityMode.HideDataCells;
settings.SettingsAdaptivity.AllowOnlyOneAdaptiveDetailExpanded = true;
settings.EditFormLayoutProperties.SettingsAdaptivity.AdaptivityMode =
FormLayoutAdaptivityMode.SingleColumnWindowLimit;
settings.EditFormLayoutProperties.SettingsAdaptivity
.SwitchToSingleColumnAtWindowInnerWidth = 600;
settings.SettingsPager.PagerSizeItemSettings.Items = new string[] { "10", "25",
"50" };
}
).Bind(Model).GetHtml()
)
Adobe XD is going to be another prototyping tool like Sketch or Balsamiq.
XD is short for Experience Design!
AutoMapper after version 4.2 requires that you hand in your own version of IMapper for Mapper and is going to want more verbose code in general going forward from that divide?
Well no, perhaps IMapper hand-ins are not required after all. jbogard suggests "5.0 is just Mapper.Initialize still. I didn't kill the static stuff, just Mapper.CreateMap" and moreover "Mapper.Initialize. There's a lambda there you add your CreateMap to. All config done once at startup"
Why is DevExpress throwing up JavaScript alerts filled with unformatted HTML and error messages?
When updating a DevExpress control with a callback in the MVC paradigm it is all important that the DevExpress control be in a partial by itself without a bunch of other HTML (or any) sprinkled inside the control as this will sabotage the callback and when the callback is called the effect of a bunch of HTML barfing up in a JavaScript alert will materialize. Also you have to update DevExpress controls (from other controls) this way (callbacks). The AJAX HTML scrape-n-splice trick won't allow DevExpress controls to function healthily. If you isolate controls into their own partials and you still see these funny errors, attach the debugger in Visual Studio 2015 and try breaking on all exceptions.
Make one DevExpress control update another in MVCland.
If you are more or less just refreshing HTML this trick for updating an MVC partial with AJAX will work, however if the partial to be updated contains another DevExpress control, lookout! You’re in trouble and things are about to get interesting. The AJAX refresh approach will paint to the screen a DevExpress control which behaves sickly with its JavaScript mechanics jacked up. For example, you might be able to display a GridView but not sort the grid. Awesome! So, what to do about that? Let's say we want one DevExpress ComboBox to update another when it's changed. Perhaps there is some sort of hierarchal relationship and the second ComboBox is subordinate to and dependent on the first with regards to what its own contents are. Alright, the actor DOING the affecting looks like so:
@Html.DevExpress().ComboBoxFor(m => m.Id, settings =>
{
settings.Name = "MerchantSelection";
settings.Properties.DropDownStyle = DropDownStyle.DropDownList;
settings.Properties.ValueField = "Key";
settings.Properties.ValueType = typeof(int);
settings.Properties.TextField = "Value";
settings.Properties.ClientSideEvents.SelectedIndexChanged = "function(s,e){
BuyerSelection.PerformCallback(); }";
}
).BindList(ViewBag.MerchantMatches.GetHtml()
Well, OK. It's not doing that much really, huh? It's just calling the callback on another control, the subordinate ComboBox. Both ComboBoxes need to be in MVC partials all by themselves. The second actor looks like this:
@Html.DevExpress().ComboBoxFor(m => m.BuyerId, settings =>
{
settings.Name = "BuyerSelection";
settings.Properties.DropDownStyle = DropDownStyle.DropDownList;
settings.ValueField = "Key";
settings.ValueType = typeof(int);
settings.Properties.TextField = "Value";
settings.CallbackRouteValues = new { Controller="Buyer", Action="ProfileBuyers" };
settings.CLientSideEvents.BeginCallback = "function(s,e){
e.customArgs['merchantId'] = MerchantSelection.GetValue(); }";
}
).BindList(ViewBag.BuyerMatches).GetHtml();
In the example at the link above (at the beginning of this blog posting) s.lastSuccessValue is handed into buyerId at a JavaScript function signature, and immediately above merchantId, sniffed off of the other ComboBox which just got set to something new, is going to be handed into the ProfileBuyers action at BuyerController, hydrating a variable there. The action will then do its thing and resurface a partial view, and it is the partial view holding the control immediately above. Get it?
Name partial views in MVC with a leading underscore and then Pascal case wording.
Similarly, regular views should be in Pascal case and match in the name of the Action that is to summon them.
When "Sql Source Control" starts acting like it can't make a connection because another instance of SSMS is open...
...you'll need to get rid of that other thing. I ended up just restarting my VM to solve this.
Saturday, October 15, 2016
When a model binds null values in the DevExpress MVC paradigm...
Per this, this:
[HttpPost]
public ActionResult Whatever(Foo foo)
{
...may need to become this:
[HttpPost]
public ActionResult Whatever([ModelBinder(typeof(DevExpressEditorsBinder))] Foo foo)
{
There is no way to insert something into a dictionary in C# and not have it last most in the perceived ordering.
Hack around this by creating a list and getting it in the right shape and then doing a .ToDictionary on it.
A lambda expression is an anonymous function in C#.
...but for the most part there are no functions in C#. One cannot use the terms function and method interchangeably as one may in some situations in JavaScript where every method is a function if not the other way around. (A method is a function hanging off of a JSON object as a property therein.) There are also Equals O'Arrow anonymous functions too in C#:
delegate void TestDelegate(string s);
TestDelegate foo = (x) => { Console.WriteLine(x); };
foo("Hello World!");
how to use a DevExpress ComboBox to update a partial view
@Html.DevExpress().ComboBoxFor(m => m.BuyerId, settings =>
{
settings.Name = "BuyerSelection";
settings.Properties.DropDownStyle = DropDownStyle.DropDownList;
settings.Properties.ValueField = "Key";
settings.Properties.ValueType = typeof(int);
settings.Properties.TextField = "Value";
settings.Properties.ClientSideEvents.SelectedIndexChanged = "function(s,e){
UpdatePartials(s.lastSuccessValue) }";
}
).BindList(ViewBag.PotentialMatches).GetHtml()
ViewBag.PotentialMatches above is a collection being handed in to the ComboBoxFor while s.lastSuccessValue is going to be handed into buyerId at the first line of code in some JavaScript (with some jQuery) here:
function UpdatePartials(buyerId){
var route = '@Url.Action("Whatever", "Buyer", new { cacheKey="guidgoeshere",
buyerId=0 });
route = route.replace('0', buyerId);
route = route.replace('guidgoeshere', '@ViewBag.CacheKey');
route = route.replace('&', '&');
$.ajax({
url: route,
type: "GET"
}).done(function(partialViewResult) {
$("#whateverWrapper").html(partialViewResult);
});
}
DevExpress controls will behave rather sickly if there is not explicitly some callouts at the top of the view to loop in needed JavaScript and CSS like so:
@Html.DevExpress().GetStyleSheets(new Stylesheet
{
ExtensionType = ExtensionType.CheckBox
})
@Html.DevExpress().GetScripts(new Script
{
ExtensionType = ExtensionType.CheckBox
})
These bits of Razor markup are control-specific so, in our case, we will need to loop in the ComboBox:
@Html.DevExpress().GetStyleSheets(new Stylesheet
{
ExtensionType = ExtensionType.GridView
}, new Stylesheet
{
ExtensionType = ExtensionType.ComboBox
})
@Html.DevExpress().GetScripts(new Script
{
ExtensionType = ExtensionType.GridView
}, new Script
{
ExtensionType = ExtensionType.ComboBox
})
The style part needs to go in the head before other styles and stylesheets. The JavaScript part could be broken out for elsewhere. Indeed the DevExpress JS should come AFTER jQuery's script tag.
This think this is how you add something to the cache in C# which will die in 15 minutes.
_cache.Add(ViewBag.Cache, buyers, DateTime.Now.AddMinutes(15));
Herein _cache is an instance of ObjectCache and buyers a List of T.
Use Html.Action to render a partial while also running its Action.
@Html.Action("Foo", "Bar", new {bar="Qux"})
...is gonna run this action in the BarController:
public ActionResult Foo(string baz)
{
DevExpress Razor markup for a callback panel in the MVC paradigm
@Html.DevExpress().CallbackPanel(settings => {
settings.Name = "myCallback";
settings.CallbackRouteValues = new { Controller="Foo", Action="Bar" };
settings.SetContent(() => {});
}).GetHtml()
These are not as life and death vital in MVC as they are in web forms. I wrote the code above seventeen days ago, never got it working, and have never needed it since. In MVC implementations of DevExpress controls one may just call out to other controls to make them refresh without a helper wrapper around everything. You don't need this stuff. You may make the callback happen from, for example, the change of a ComboBox control like so:
settings.Properties.ClientSideEvents.SelectedIndexChanged = "function(s,e){
myCallback.PerformCallback(); }";
The connectors for lightning ports have pins on the outside and the connectors for USB Type C have pins on the inside but are otherwise about the same.
Lightning ports replace a 30 pin connector's connection at iPhone 5 and up while the older phones expect that you have USB to 30 pin cords.
deterministic versus nondeterministic
That which is deterministic will return consistent results every time, like math functions, while that which is nondeterministic has a little play in the steering if you will. DateTime.Now doesn't give you the same thing whenever you ask for it in C# for example.
IAC or InterActive Corp which owns match.com, Tinder, and OkCupid pretty much has a lock on the dating site space.
eHarmony is going to be an exception to the not-quite monopoly.
In abandoning "check in early and often" and trying to have as few merges as possible, it begs the question: Should I merge "early and often" eh?
...or alternatively should I just have one big merge at the end. There is no consensus amongst my coworkers. If I have one big merge at the end, it should make it easier to make a safety copy of the whole codebase (if repeated as a chore constantly this is annoying) in advance of pulling down possibly breaking changes.
You may make free phone calls over Facebook.
I didn't know this until recently but it's pretty cool. Both parties need to have Facebook up and to be connected to the internet over Wi-Fi I think. I don't really know much about it.
Friday, September 30, 2016
Tech Fail!
I took these photos on 7/10/2016 at Arlanda Airport just north of Stockholm, Sweden whilst on vacation.
I'm not sure what was supposed to be on the display, but I am sure the wrong thing is being communicated.
Tuesday, September 27, 2016
'ref' argument is not classified as a variable
This error message which may be found in Visual Studio 2013 also appears in Visual Studio 2015 only therein it is the second of two lines of error messages. The first is:
A property of indexer may not be passed as an out or ref parameter
Perhaps it's now a little more clear what is going wrong, eh? The problem would occur at the last line of this code for example...
var buckToothedTreeGnawers = new List<Beaver>()
{
new Beaver()
{
Name = "Flotsam",
MillimetersOfTeeth = 30
},
new Beaver()
{
Name = "Jetsam",
MillimetersOfTeeth = 29
},
new Beaver()
{
Name = "Lagan",
MillimetersOfTeeth = 40
}
};
var lumber = Woods.ChopDownPine(ref buckToothedTreeGnawers[2]);
buckToothedTreeGnawers[2] will get the squiggly red line under it in Visual Studio letting you know that something is wrong and when you roll your mouse pointer over it... Voilà! There is our error! You cannot hand a ref variable into a method signature while referencing it out of a list. Whatever. I don't see why not, but then I don't make the rules. I'm not Anders Hejlsberg. Anyhow, code like this will actually work:
var flotsam = new Beaver()
{
Name = "Flotsam",
MillimetersOfTeeth = 30
};
var jetsam = new Beaver()
{
Name = "Jetsam",
MillimetersOfTeeth = 29
};
var lagan = new Beaver()
{
Name = "Lagan",
MillimetersOfTeeth = 40
};
var lumber = Woods.ChopDownPine(ref lagan);
I think you'll find this shortcoming won't get in your way all that much really. I only stumbled upon it today for the first time and I've written C# for ten years.
flash drives have "solid state storage"
...as opposed to a spinning disc making them vaguely twice as fast. Also, there are fewer moving parts to break.
PHP at NGiNX
FastCGI will allow you to run PHP on NGiNX. Another approach is to run let Apache run PHP and use NGiNX merely as a router (as a front door to Apache). NGiNX is apparently petty light in and of itself.
Monday, September 26, 2016
CTE within SUM or COUNT!
Starting with this T-SQL and improving upon it gives us:
SELECT c.CurrencyId AS 'Id'
c.CurrencyCode,
COUNT(i.TotalAmount) AS 'OpenInvoices',
COALESCE(SUM(i.TotalAmount), 0) AS 'Balance',
(SELECT COUNT(TotalAmount) FROM #Invoices
WHERE DueDate < GETDATE() AND Id = CurrencyId) AS 'OpenInvoices',
COALESCE((SELECT SUM(TotalAmount) FROM #Invoices
WHERE DueDate < GETDATE() AND Id = CurrencyId), 0) AS 'Balance',
FROM #Currencies c
LEFT JOIN #Invoices i ON c.CurrencyId = i.CurrencyId
GROUP BY CurrencyCode
Note that if you want to use a column from another table not specified in your CTE that it better be one of the columns returned in the select statement. Otherwise, expect an error. To that end I've looped CurrencyId into the list of columns returned and have fudged its name so there is no ambiguity when matching CurrencyId to CurrencyId in my CTEs without a leading c. or i. to distinguish them.
Use COALESECE in T-SQL to make columns which sum up nothing return a zero instead of NULL.
This...
SELECT c.CurrencyCode,
COUNT(i.TotalAmount) AS 'OpenInvoices',
SUM(i.TotalAmount) AS 'Balance',
COUNT(pdi.TotalAmount) AS 'PastDueInvoices',
SUM(pdi.TotalAmount) AS 'PastDueBalance'
FROM #Currencies c
LEFT JOIN #Invoices i ON c.CurrencyId = i.CurrencyId
LEFT JOIN #PastDueInvoices pdi ON c.CurrencyId = pdi.CurrencyId
GROUP BY CurrencyCode
...needs to become...
SELECT c.CurrencyCode,
COUNT(i.TotalAmount) AS 'OpenInvoices',
COALESCE(SUM(i.TotalAmount), 0) AS 'Balance',
COUNT(pdi.TotalAmount) AS 'PastDueInvoices',
COALESCE(SUM(pdi.TotalAmount), 0) AS 'PastDueBalance'
FROM #Currencies c
LEFT JOIN #Invoices i ON c.CurrencyId = i.CurrencyId
LEFT JOIN #PastDueInvoices pdi ON c.CurrencyId = pdi.CurrencyId
GROUP BY CurrencyCode
Get it?
You may skip the empty curly braces when newing up a list in C# if you like.
var buckToothedTreeGnawers = new List<Beaver>();
...and...
var buckToothedTreeGnawers = new List<Beaver>() { };
...are basically the same thing.
VoIP stands for Voice Over Internet Protocol
The last blog posting I just typed up made me think of Voice over IP. This stuff allows your business telephone to interface with your PC, etc. You can get voicemail messages as email attachments and the like.
marketing misadventures
There are two different members of the waitstaff at the Olive Garden that I always eat at who are trying to improve their lot and get into marketing and out of service. One of them is a young guy whom, to me it sounds, has landed his first office job gig in the marketing space. I think it's gonna be mostly office admin stuff, but there will be some email campaign marketing going on there too. It sounds like a good start. I certainly had to answer the phone a lot in my day, and there was a time when I was in restaurants too, making sandwiches at Texadelphia or bussing tables at Fresh Choice. To this day my heart bleeds for people suffering in service jobs who don't want to be there because I've been there myself. I always tip well. I digress. The other person is a woman my age with a large history in pharmaceutical marketing in New Jersey (including focus groups!) who has moved to Texas and is trying to find her footing here. They both have me thinking of marketing in general. I really don't know that much about it, all in all. I've gotten to work some with Christa Tuttle and Shawna Boyce of Launch Marketing and I get the impression that the typical background is one of a bachelors in, well, marketing, which is an awful lot like a generic bachelors in business with only a few classes differing, just enough to make a specialization of a business degree. From Launch I learned that anymore to make a press release you just write something up and put in on your web site. Maybe back in the day you had to have a press kit, but not anymore. I don't know what a press kit even is and if it varies from a press packet and opens other doors. Someone with the formal background knows these things. Eleven years ago towards the end of my time at Network Logistic, Inc. I was given the grandiose, ridiculous title of Director of Marketing before I had ever rubbed elbows with a real marketer. Before then I had designed some marketing slicks when I worked for Gary McKibben and Michael Johnson at Johnson/McKibben Architects and I had made some 3D models for presentations when I both did a week long contract with Joel Shakespear at a now dead startup called TRiAD and a much longer stint for John Drury at his slaveworks, but this isn't really, obviously, the background for someone who is a Director of Marketing. What a joke. I made twelve dollars an hour in this role, and, it gets better, all I did was the web developer job I had before while I also now sent out email campaigns. Yes! Plus, there was no one to direct. I was director without underlings. This is the kind of place that would give the title Vice President of Sales or Vice President of Engineering out like it was nothing. I guess it was a part of their posturing as they hired staff on the cheap while acting as if not Mickey Mouse in whole. Paul Williams, an engineer who worked at NLI, suggested that I shouldn't feel awkward about my bogus title because "There's nothing to those fucking people." However, when I eventually started to really know some of them I found them pretty impressive and I wished I knew more of what they knew. I eventually grew some SEO (search engine optimization) chops, but I've let that skill decay and I can't really do it anymore. That other Tom Jaeschke, the volleyball player, always appears when I Google my own name. Yeesh. I ran into Stacy Tallent of Telco-Data maybe a year ago at a, well, Texadelphia, and he spoke well of me for designing the logo that they are still using today way back when Telco-Data and Network Logistic, Inc. were sister companies sharing a common owning partner. I've never learned much of anything about telephony. I can remember Penn Rabb of PrismNet expressing some frustration with me for not knowing more about a business telephone system I was using. Whatever. I digress again. Anyhow, I think I shall always find marketing intriguing and have an ear open to it. It's on my mind right now.