# Workspace configuration
- setup project the hardway (we want to use webpack)
- create a build directory (either ant or dx) to handle deploying meta-data (page, controller, static resource)
- add package.json scripts to compile -> copy assets to build -> deploy
```
"scripts": {
"build": "webpack --config config/webpack.config.js && npm run prepare",
"prepare": "cp dist/app.js build/package/StaticResources/App.resource && cp -r src/salesforce/* build/package",
"push": "ant deploy -buildfile build -Ddir build/package",
"deploy": "npm run build && npm run push",
"start": "webpack-dev-server --config config/webpack.config.js --https"
}
```
## serving locally
1. Setup page to toggle scripts on URL param (`?local=1`):
```
```
2. run `npm start` to use webpack to serve content locally. Will refresh page eveything you save
# Working with SF data
## RemoteObjects
1. Create typings
```
//this is super confusing but it works... https://github.com/Microsoft/TypeScript/issues/6413
export abstract class RemoteObject{}
export interface RemoteObject {
get?(field: string): string;
set?(field: string, value: string);
retrieve?(args: any, callback: RetrieveCallbackType);
//todo: implement rest of methods
}
interface RetrieveCallbackType { (err:any, records:RemoteObject[], event:any): void }
export class RemoteObjectModel {
Account: {new(p: any): RemoteObjectModel.Account}
}
export namespace RemoteObjectModel {
export class Account extends RemoteObject{
constructor(values: any){super()}
}
}
```
For every remoteModel you add, you'll have to add code for:
a. `MySObject: {new(p: any): RemoteObjectModel.MySObject}` to `RemoteObjectModel` class
b. A new class (`MySObject`) to the `RemoteObjectModel` namespace that extends `RemoteObject`
2. setup `remoteObjects` in vf page
```
```
3: call remote object
```
let account: RemoteObjectModel.Account = new this.props.remoteObjectModel.Account({});
account.retrieve({limit:10},(err, records, event) => {
console.log(err,records,event);
if(err) {
alert(err.message);
}
else {
records.forEach(function(record) {
console.log(record.get('Name'));
});
}
});
```
3. An object called `remoteObjectModel` (based on `jsNamespace`) will be injected into global scope automaticly
4. declare a var in your app: `declare var remoteObjectModel: RemoteObjectModel;`
## Rest API
1. `npm install axios --save` https://github.com/mzabriskie/axios
2. inject token into global scope ``
3. declare a var in your app: `declare var accessToken: string;`
4. make callout using token. Can generate types from response using something like http://json2ts.com/
[Type Assertions vs Casting](https://basarat.gitbooks.io/typescript/content/docs/types/type-assertion.html)
Example, You call the rest API and assert that the response is of type `Account`
```javascript
public class Account{
public foo(){
}
public Name: string;
}
let acc : Account = Rest.query('select Name FROM Account limit 1');
```
While the system may let you do this, and some other the properties do line up, when you go to access `.foo` on the returned object, you will get undefined.
The proper way to do this would be to use `Object.Assign(new Account(), Rest.query('select Name FROM Account limit 1'));`. This creates a new Account instance and copies over the properties!