How to set value not contained in map with RxJS? - javascript

I am just getting started with Angular 4, and have a project I've been working on that involves displaying data that is retrieved using a REST API. The data seems to be getting retrieved properly and the form getting populated correctly.
Now, one of the values returned from the API only contains a single character. I was hoping to override the setter method to expand that single character to a full string. I understand I could just change the call to return the full string, however the API is supporting by multiple front-ends and I was hoping to keep them consistent. This plunker should what I am hoping to do (without the REST API involved): Plunker example
When logging in the subscribe function of my project, fullStatus is not included:
this.service.get(id).subscribe(p => {
this.test = p;
console.log(this.test);
});
When adding the switch statement here, things work as intended, however I was hoping to have this logic be bundled into the Test class instead of the subscribe function.
this.service.get(id).subscribe(p => {
this.test = p;
switch (this.test.status) {
case 'A':
this.test.fullStatus = 'Active';
break;
case 'I':
this.test.fullStatus = 'Inactive';
break;
case 'N':
this.test.fullStatus = 'No Certificate';
break;
default:
this.test.fullStatus = '';
break;
}
console.log(this.test);
});
Is there a better way for me to handle this? Thanks in advance.

Can't you do a map of your results after the api call to include this fullStatus property?
In your service,
// assuming you have to convert the response to json
get(id) {
return this.http.get(<url-to-get>).map((res) => {
let test = res.json();
switch (this.test.status) {
case 'A':
test['fullStatus'] = 'Active';
break;
case 'I':
test['fullStatus'] = 'Inactive';
break;
case 'N':
test['fullStatus'] = 'No Certificate';
break;
default:
test['fullStatus'] = '';
break;
}
return test; // returns each response element with the new property 'fullStatus' added based on its 'status'
});
}
Then you can simply subscribe it in your component class. Hope it helps.

You can create a test class like test-model.ts :
export class Test {
prop1 = ''; // dummy property (you can define these according to your need
prop2 = '';
status: string;
fullStatus?: string; // optional
init(responseData: any){
this.prop1 = responseData.prop1 ;
this.prop2 = responseData.prop2 ;
this.status = responseData.status;
switch (responseData.status) {
case 'A':
this.fullStatus = 'Active';
break;
case 'I':
this.fullStatus = 'Inactive';
break;
case 'N':
this.fullStatus = 'No Certificate';
break;
default:
this.fullStatus = '';
break;
}
}
}
In the component:
import {Test} from './test-model';
export class TestComponent implements OnInit
{
test: Test = new Test();
constructor(private service: MyService){}
ngOnInit(){
this.service.get(id).subscribe(p => {
this.test.init(p);
console.log(this.test);
});
}
}

Related

How do i exclude namespace functions when iterating over an enum?

I have the following code
export enum JournalEntryType {
ORDINARY_JOURNAL_ENTRY = 'ORDINARY_JOURNAL_ENTRY',
PLANT_TRANSPLANTED = 'PLANT_TRANSPLANTED',
SOW_SEEDS = 'SOW_SEEDS',
SEEDS_GERMINATED = 'SEEDS_GERMINATED',
PLANT_BLOSSOMS = 'PLANT_BLOSSOMS',
FRUIT_SETTING = 'FRUIT_SETTING',
FRUIT_CHANGED_COLOR = 'FRUIT_CHANGED_COLOR',
HARVEST = 'HARVEST',
ANIMAL_SIGHTING = 'ANIMAL_SIGHTING'
}
export namespace JournalEntryType{
export function getJournalEntryTypeColor(journalEntryType: string): string{
switch(journalEntryType){
case JournalEntryType.ORDINARY_JOURNAL_ENTRY.toString(): return '#FFFFFF';
case JournalEntryType.PLANT_TRANSPLANTED.toString(): return '#8B4513';
case JournalEntryType.SOW_SEEDS.toString(): return '#D2691E';
case JournalEntryType.SEEDS_GERMINATED.toString(): return '#7CFC00';
case JournalEntryType.PLANT_BLOSSOMS.toString(): return '#FFB6C1';
case JournalEntryType.FRUIT_SETTING.toString(): return '#FF69B4';
case JournalEntryType.FRUIT_CHANGED_COLOR.toString(): return '#ff1493';
case JournalEntryType.HARVEST.toString(): return '#DC143C';
case JournalEntryType.ANIMAL_SIGHTING.toString(): return '#800080';
default: throw new Error();
}
}
}
When i iterate over JournalEntryType and log every value like so:
for(let journalType in JournalEntryType){
console.log(journalType);
}
The last value that is printed won't be ANIMAL_SIGHTING but getJournalEntryTypeColor. In other words, it also iterates over any functions that are declared in the namespace. How do i prevent this from happening? I've tried filtering out the method with an if statement that checks whether the type of the journalTypeis a string. But that won't stop from getJournalEntryTypeColor getting printed as well.
The key thing is that you need to check the type of the property on the object, not the type of the key.
Object.keys(JournalEntryType)
.filter(journalType => !(typeof(JournalEntryType[journalType]) === 'function'))
.forEach(journalType => {
//code here
});
(This code is taken from the comments, it was written by Maurice.)

Switch Statement and jQuery hasClass function

I am trying to use a switch statement to check if the current page has a specific body class. This is kind of what I am looking for:
var bodyClass = $('body').hasClass('className')
switch(bodyClass) {
case 'homepage':
// console.log("This is the homepage");
break;
case 'residential-page':
// console.log("This is the residential page");
break;
default:
// console.log("default code block ran");
}
I do understand that the jQuery hasClass function returns true of false and is used like $('body').hasClass('someClassName') and this will return true or false. Also, my body typically has about 7-10 different class names for a given page.
This is not the use case for a switch in my opinion, but a simple set of branches
var body = $('body');
if(body.hasClass('abc')) {
}
else if(body.hasClass('def')) {
}
else {
/* default case */
}
/* etc */
I agree with the other answer that you're better suited to just use if, else if statements here, but an alternative would be to rip the classes off the body tag and check them against your strings:
var bodyClasses = ($('body').attr('class') || '').split(' ');
for (var i = 0, len = bodyClasses.length; i < len; i++) {
switch(bodyClasses[i]) {
case 'homepage':
// console.log("This is the homepage");
break;
case 'residential-page':
// console.log("This is the residential page");
break;
default:
// console.log("default code block ran");
}
}
I know this is an old thread, but it may help someone else.
If you are able to ensure the classes for the element are declared in a specific order, you could ensure the class you are checking for is first / last in the list, and use something similar to this:
var bodyClass = $('body').attr('class');
var firstClass = bodyClass.slice(0, bodyClass.indexOf(' '));
switch(firstClass) {
case 'homepage':
// Some code here
break;
case 'residential-page':
// Other code here
break;
default:
// More code here
}

How to simplify this switch statement (Angular app)

I'm using a modalService to store modal templates in my mainController.
Here is how I store them (from mainController)
// Store popup modal:
$ionicModal.fromTemplateUrl('app/popup/popup.html', {})
.then(function(modal) {
PopupFactory.storeModal(modal);
});
// Store addTicker modal:
$ionicModal.fromTemplateUrl('app/tickers/addTicker.html', {})
.then(function(modal) {
ModalFactory.storeModal('addTicker', modal);
});
modalFactory
This is what the storeModal function looks like:
function storeModal(type, modal) {
switch(type) {
case 'addTicker':
vm.addTicker = modal;
break;
case 'addTag':
vm.addTag = modal;
break;
}
}
^ as you can see I have to create an object for each modal my app will have.
This is what the getModal function looks like:
function getModal(type) {
switch(type) {
case 'addTicker':
return vm.addTicker;
break;
case 'addTag':
return vm.addTag;
break;
case 'anotherModal':
return vm.anotherModal;
break;
case 'yetAnotherModal':
return vm.yetAnotherModal;
break;
}
}
I feel like this code can be optimized to 1 or 2 lines...
I've tried the follow to no avail:
function getModal(type) {
return vm.+type;
}
and
function getModal(type) {
var returned = type;
return vm.returned;
}
However when I call getModal in the respective Directive Controllers, I get undefined:
function addTickerButton() {
vs.addTicker = ModalFactory.getModal('addTicker');
vs.addTicker.show('addTicker);
$rootScope.$emit("modal.add.tickers");
}
You got very close here:
function getModal(type) {
var returned = type;
return vm.returned;
}
But you are trying to access a returned attribute on vm, which doesn't exist. To retrieve an attribute using a variable, you must use bracket notation:
function getModal(type) {
return vm[type];
}
Just do
function getModal(type) {
return vm[type];
}
What you need is an object accessor with bracket notation:
vm[type] = modal
See this link for more details.

Javascript switch statement using regular expressions

I'm attempting an exercise and can't quite understand where I'm going wrong.
I have a form where my postcode field will only validate if it meets the requirements of the regex specific to the state chosen.
I need to use a switch statement to determine what RegEx to use based on the state choice.
This is what I have so far:
function validPostCode() {
var state = (document.getElementById("state").value);
switch (state) {
case "SA":
var stateRegEx = /^5([0-9]{3})$/;
break;
case "NSW":
var stateRegEx = /^2([0-9]{3})$/;
break;
}
return stateRegEx.test(document.getElementById("postcode").value);
}
Try this:
function validPostCode() {
var state = (document.getElementById("state").value);
var stateRegEx; // added here
switch (state) {
case "SA":
stateRegEx = /^5([0-9]{3})$/; // var removed
break;
case "NSW":
stateRegEx = /^2([0-9]{3})$/; // var removed
break;
}
return stateRegEx.test(document.getElementById("postcode").value);
}

Can you access local static variables within local method in TypeScript?

Lets say I have a class like below:
class Types
{
static TypeOne = 1;
static TypeTwo = 2;
static TypeThree = 3;
static TypeFour = 4;
static TypeFive = 5;
public GetNameFromType(type: number) : string
{
switch (type)
{
case Types.TypeOne: return "TypeOne";
case Types.TypeTwo: return "TypeTwo";
case Types.TypeThree: return "TypeThree";
case Types.TypeFour: return "TypeFour";
case Types.TypeFive: return "TypeFive";
default: return "Unknown";
}
}
}
Now after reading some documentation on static classes it seems like the above should work. however I keep getting an error saying that Types.TypeOne does not exist in the current scope.
So do I need to do anything else or should this just work?
== Edit ==
I didnt think it was outputting anything for it due to the errors, but it appears it has, here is the output:
var Types = (function () {
function Types() { }
Types.TypeOne = 1;
Types.TypeTwo = 2;
Types.TypeThree = 3;
Types.TypeFour = 4;
Types.TypeFive = 5;
Types.TypeSix = 6;
Types.prototype.GetNameFromType = function (type) {
switch(type) {
case AbilityTypes.TypeOne:
return "TypeOne";
case AbilityTypes.TypeTwo:
return "TypeTwo";
case AbilityTypes.TypeThree:
return "TypeThree";
case AbilityTypes.TypeFour:
return "TypeFour";
case AbilityTypes.TypeFive:
return "TypeFive";
case AbilityTypes.TypeSix:
return "TypeSix";
default:
return "Unknown";
}
};
return Types;
})();
This looks legit, so maybe it is working and is just complaining...
Are you using Typescript 0.8.3? Your code compiles fine for me. If the error is happening else where, try and define them as a 'public static'
Pasting that code into the Playground ( http://www.typescriptlang.org/playground ) shows no errors or warnings for me, and this is running the same 0.8.3 bits as the MSI. I would uninstall/reinstall if you are seeing errors with just this code, as unless this is part of a larger project and the error is occurring elsewhere, then seems like something in the install must be out of whack.

Categories

Resources