Technology Problem Fit / Technology Market Fit

Product Market Fit (pmf) has rightfully became a popular approach for many startups.  However, in some cases when you already have deep technical knowledge (deep tech); changing underlying technology of your product is not an option since it would erode your competitive advantage.  In this case; a more advantageous approach could be Technology Problem Fit (tpf) or a broader Technology Market Fit (tmf).

Posted in Uncategorized | Leave a comment

AWS API Gateway – Lambda CORS troubles: Access to fetch at execute-api from origin cloudfront.net has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

Problem

Access to fetch at execute-api from origin cloudfront.net has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

Solution

First of all; I assume you already have CORS enabled via API Gateway (also don’t forget to deploy it).

In my case the problem was on the lambda side.

I was using ASP.net Core and it was doing its own CORS checks (you can easily see this via CloudWatch logs).

To allow any requests through you can add the following to corresponding methods in Startup.cs

            services.AddCors(o => o.AddPolicy("AllowAllPolicy", builder =>
            {
                builder.AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader();
            }));

////////

            app.UseCors("AllowAllPolicy");

 

 

 

Posted in Uncategorized | Leave a comment

Azure Functions: System.InvalidOperationException: ‘The host has not yet started.’

Problem

was getting the following exception

System.InvalidOperationException: 'The host has not yet started.'

System.InvalidOperationException
  HResult=0x80131509
  Message=The host has not yet started.
  Source=Microsoft.Azure.WebJobs.Host
  StackTrace:
   at Microsoft.Azure.WebJobs.JobHost.StopAsync() in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\JobHost.cs:line 121
   at Microsoft.Azure.WebJobs.Hosting.JobHostService.StopAsync(CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Hosting\JobHostService.cs:line 32
   at Microsoft.Extensions.Hosting.Internal.Host.<StopAsync>d__10.MoveNext()

 

Solution

Solution was non-intuitive; after a couple of hours of trial and error; have finally got it to work.  Fix is easy; just need to set:

Project Properties/Build/General/Platform target: “Any CPU”

p.s. previously was “x64”

 

 

 

Posted in Uncategorized | Leave a comment

Microsoft.Azure.WebJobs.Host: Error indexing method ‘HubFunction.Run’. Microsoft.Azure.WebJobs.ServiceBus: Value cannot be null.

Got the following errors when trying out Azure’s Event Hub trigger for Azure Functions

Warning: Cannot find value named 'Endpoint=sb://DDDD' in local.settings.json that matches 'connection' property set on 'eventHubTrigger' in 
You can run 'func azure functionapp fetch-app-settings <functionAppName>' or specify a connection string in local.settings.json.

original code:
public static void Run([EventHubTrigger(“ais-hub”, Connection = “Endpoint=sb://MY-ENDPOINT…”)]string myEventHubMessage, TraceWriter log)

Connection string–primary key needs to be in `local.settings.json`

“EventHubConnection”: “Endpoint=sb://MY-ENDPOINT…AND OTHER DETAILS”

and then in code referenced as

 public static void Run([EventHubTrigger("hub1", Connection = "EventHubConnection")]string myEventHubMessage, TraceWriter log)

 

Next Problem

After this was solved the next problem that will likely popup is:

The listener for function was unable to start. Microsoft.ServiceBus: The messaging entity ‘Management operation failed. status-code: 404, status-description: The messaging entity sb://<private>.servicebus.chinacloudapi.cn could not be found..’ could not be found. EventHubTrigger “eventHubName”

The problem was due to me not realizing that was I’ve created with the Azure portal was a hub namespace (and not the hub with a certain name); that needs to be done within the namespace; e.g.:

 

 

 

 

Posted in Uncategorized | Leave a comment

Evaluating Startup

There are many articles about how to evaluate startups.  I wanted to add my 2c.

An approach that I’ve recently stumbled upon; when evaluating startup is to trying to find a great aspect about it (or imagine how it could become great).  Hypothesis is that this single great characteristic is what could make the startup take off; other parts could be imperfect and solved at later time.

p.s. coming from technical and academic backgrounds; I’ve been trained to identify weaknesses; so this approach is new to me.  It is often very hard to find the great aspects/potential; in fact much harder than to criticize something.  Am looking forward to getting better at it.

acknowledgement: this arose from conversations with my mentors and pondering things …

Posted in Uncategorized | Leave a comment

Adding Typescript to AWS Amplify React

Here are a few small changes that you need for enabling support for typescript in AWS Amplify React

 

in tsconfig.json change target to:

"target": "es6",

 

Then install necessary packages (here are the basic ones):

 
npm install typescript --save
npm i @types/node --save
npm i @types/react --save
npm i @types/react-dom --save

 

To make sure that it work try a simple example from: https://github.com/Microsoft/TypeScript-React-Starter

// src/components/Hello.tsx

import * as React from 'react';

export interface Props {
    name: string;
    enthusiasmLevel?: number;
}

function Hello({ name, enthusiasmLevel = 1 }: Props) {
    if (enthusiasmLevel <= 0) {
        throw new Error('You could be a little more enthusiastic. :D');
    }

    return (
        <div className="hello">
        <div className="greeting">
            Hello {name + getExclamationMarks(enthusiasmLevel)}
    </div>
    </div>
);
}

export default Hello;

// helpers

function getExclamationMarks(numChars: number) {
    return Array(numChars + 1).join('!');
}

 

and then modify your App.js with:

<div className="App">
    <div>
        <Hello name="TypeScript" enthusiasmLevel={10} />
    </div>
..........

 

To make sure all is good run:

npm run build
npm run start

 

just in case how my config files look like

package.json

{
  "name": "startup_details_viewer",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@types/node": "^10.12.3",
    "@types/react": "^16.7.1",
    "@types/react-dom": "^16.0.9",
    "aws-amplify": "^1.1.9",
    "aws-amplify-react": "^2.1.3",
    "react": "^16.6.1",
    "react-dom": "^16.6.1",
    "react-scripts": "2.1.1",
    "typescript": "^3.1.6"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ]
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es6",
    "allowJs": true,
    "skipLibCheck": false,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve"
  },
  "include": [
    "src"
  ]
}

 

 

 

Keywords

Try changing the `lib` compiler option to es2015 or later. TS2585 aws amplify
typescript aws amplify

 

 

Posted in Uncategorized | Leave a comment

2018 Best Laptop for Startup’s Technical Founder

I have an analytical mindset; which is a blessing and a curse.  Am having great time working on my startup sectormap.net but then spend way too much time on trying to decide what to buy (laptop in this case).

Spoiler: clear winner in my case was HP Envy x360 15 inch
p.s. that was a surprise; since HP wasn’t even on my list

Must Have Features

  • fast
    • Kaby Lake Refresh CPU i5 or better
    • PCIE NVME ssd drive
  • long battery life (6+ hours)
  • 4K external display capability (60 hz)
    • hdmi 2.0 or DisplayPort or Thunderbolt (p.s. hdmi2 is only available on recent monitors …)
    • hard criteria to satisfy (surprisingly)
  • upgradability (ram, hdd)
    • upgradable ram is rarity; significantly narrow downs options (also preferably 2 slots for faster speed via dual channel capability

 

Nice to Have Features

  • 2-in-1 convertible: for doing client demos
  • usb-c charging function
  • nice design
  • small ~13.3
  • not heavy (under 2 kg)
  • mate screen

 

List of laptops that satisfy my criteria is surprisingly short.

HP Envy x360 15 inch has exceeded my expectations; love the design; 2-in-1 functionality; satisfied all of the must have features; and many of the nice to have

Dell XPS 15: nice but pricey ~1,500$

Lenovo: Thinkpad E480 (least expensive candidate), T480/S, L380, X1; IdeaPad 920S
super slow delivery ~1 month; couldn’t wait that long; and by that time something better might be around so would have remorse about that …

 

Update

After using laptop for 2 months; am pretty satisfied with it (although longer battery life could be handy; lasts about ~5 hours).

Unexpected bonus was the handiness of touch screen while giving presentation; e.g. can use presenter’s tool of powerpoint e.g. (virtual) laser pointer; or drawing tools to annotate slides as I am presenting them.

Glossy screen is definitely a nuisance, but workable.

 

keywords: programming development laptop ultrabook

 

 

Posted in Uncategorized | Leave a comment

Startup: registering / running corporation in Hong Kong (Banking, etc.)

Summary

  • free, simple & fast bank account opening with Neat (don’t need to visit HK)
  • $200 UD (setup), and $1,200 USD for annual running costs; by using Kams  (accounting, audit, office services; in simple case; government fees are excluded)

Details

As a startup, in most jurisdictions you have to spend a lot of time/money proving the obvious – that your startup is either losing money or is barely profitable (most income being redirected towards growth); so that you don’t get taxed even though you are not making any profit yet.

I did a fair amount of research * and Hong Kong was the only jurisdiction that I’ve found that had a combination of very little paperwork and is inexpensive for setup, operations/running (and is not in shady offshore locations).

In Hong Kong it is easy to register and operate your startup (even if you are not physically located in HK).  I hope information bellow helps somebody to start pursuing their startup dreams; and at least makes the operations part easier.  Good Luck !!!

Banking

Neat Business is a lifesaver; it takes care of all of your banking needs; gets you a bank account number and everything you need to run your startup (accepting payments via stripe, etc.); and you don’t even need to visit Hong Kong to open the bank account.  It took me less than a week to get an account and a corporate mastercard debit card (thanks a lot Neat).

Here is why I have so much appreciation for Neat.  Over the past years it has become ridiculously hard to open a bank account in HK; e.g. winner of startup competition at a local university wasn’t able to open account (ref), troubles of another startup (ref) .  p.s. many of the HK banks had to pay 100 of millions of “fines” to US; and now naturally don’t want to open accounts to companies that don’t have verifiable history and operations; which unfortunately includes many of the startups 🙁

p.s. I have account at traditional banks in HK; but will be shifting most things to Neat.

Company Setup / Operations

Kams is the company that I use and highly recommend for all of the corporate operations/running needs (setup, company secretary, registered address, accounting, audit, etc.).  They do everything professionally and expediently; and at a very good price; my operations are simple and per year for all of the services I am paying less than 1,200 $US (could be different in your case; but still probably very reasonable).

 

Notes

* Estonia (used to be good; but now it’s almost impossible to open bank account).  Initially I was planning just to setup company locally in either Canada, Japan, US (via Stripe Atlas); all of which would require significant paperwork for operations.  Time is something that many of the startups do not have a surplus of.

 

keywords: corporation startup hk hong kong bank account company setup running audit  dbs hsbc bank of china  … bank account

 

Posted in Uncategorized | Leave a comment

Play Json with Scala Trait

To be able to use trait with Play Json; you need to provide un/apply methods for the trait; and define a case class that could be instantiated.

(there might be a better approach)

 

import play.api.libs.json.Json
trait PaginatedTrait {
  def total: Int
  def per_page:Int
  def page: Int
  def last_page: Int
}

object PaginatedTrait  {

  def apply(
             total: Int,
             page: Int,
             per_page: Int,
             last_page: Int
           ): PaginatedTrait = new PaginatedRec(total, page, per_page, last_page)


  def unapply(x: PaginatedTrait): Option[(Int, Int, Int, Int)] = Some(x.total, x.page, x.per_page, x.last_page)

  implicit val formatPaginatedTrait = Json.format[PaginatedTrait]
  implicit val writesPaginatedTrait = Json.writes[PaginatedTrait]
  implicit val readsPaginatedTrait = Json.reads[PaginatedTrait]

}

import play.api.libs.json.Json

case class PaginatedRec(
                         override val total: Int,
                         override val page: Int,
                         override val per_page: Int,
                         override val last_page: Int
                       ) extends PaginatedTrait
{
}


// This might not be required
object PaginatedRec{
  implicit val paginatedTraitRecFmt = Json.format[PaginatedRec]
  implicit val paginatedTraitRecWrites = Json.writes[PaginatedRec]
  implicit val paginatedTraitRecReads = Json.reads[PaginatedRec]
}

 

 

 

 

keywords:

scala unapply method for trait in companion object

scala apply method for trait in companion object

scala apply method in object

scala No apply function found for trait json

scala No apply function found for trait

play json No apply function found for trait

 

 

Posted in Uncategorized | Leave a comment

Using Lambda with multiple handlers in AWS Step Functions

Problem

Using lambda function with multiple handlers is non-trivial in AWS Step Functions

Solution

Lambda is great; however one of the limitations is that only a single handler function is used.  Maintaining multiple lambda functions gets cumbersome quickly.

One common approach is to have a meta  handler that then routes to one of the sub-handlers; typically this is done by passing a name/reference to a handler to be used.

Now the problem arises when one wants to use meta-handlers  with AWS Step Functions.  In particular, it is not possible to edit the message (input/out) that is passed around states.

While editing message is not possible; one can alter it by moving different parts of it around.  It is a little bit tricky since one would have to use a combination of InputPath , ResultPath and OutputPath .  Currently a way to achieve is as following.

{
  "handlers": {
    "h1": {
      "name": "h1"
    },
    "h2": {
      "name": "h2"
    }
  },
  "handler": {
    "name": "doMyThing"
  },
  "details": {
    "path": "yourPath"
  }
}

In your request include handlers that lists the ones that you are planning to use.

Then you you can add a pass state in the AWS Step Function’s State machine to select which of the handlers should be used; here is an example (selecting h1 to be used as a handler for the next state)

{
 "StartAt": "test",
 "States": {
 "test": {
 "Type": "Pass",
 "InputPath": "$.handlers.h1", 
 "ResultPath": "$.handler", 
 "OutputPath": "$",
 "End": true
 }
 }
}

 

 

 

Posted in Uncategorized | Leave a comment