#Xamarin: It’s actually about the money

ca44147d22ccf7fe745b9a59e0054e7c.gifAs developers, we naturally focus on the tech side of tech. Xamarin is a great toolset that allows you to create native, fast apps with a single codebase using the .Net you already know and love.

However, I think the key benefit, the one that gets overlooked in reviews and overviews of the software, is that Xamarin saves your company money. People are expensive so not having to hire an iOS and Android team, and not having to retrain the developers in a language they may not know saves a significant amount of money.

At Maximizer, a long-standing CRM company,  we focus on building great tools, but tools that are affordable as well. The app team which I lead has only 1 group of developers focusing on building a great CRM app. We have one set of Program Managers supporting the single team. There is one build process and one deployment process. No effort is needed to keep the Android and iOS teams in sync as there is only one codebase.

So, glory in the technical wonders of Xamarin, but smile at the money you are saving your company and customers.

I wrote this post after I was surprised as the level of interest in Xamarin and money-saving of one of my recent Twitter posts.

Screenshot 2020-01-21 at 8.27.31 AM.png

 

 

 

#Xamarin Animated #GIFs

In the latest version of Xamarin , version 4.4, Images can now show animated GIFs.

Normally my posts are a bit longer to explain how to implement a new Xamarin feature, but this one is so simple, yet powerful, that only a small post is needed.

Sweet.

The Image tag now has an attribute called IsAnimationPlaying. Set that to true and the source to an animated GIF, either local or remote.

That’s it. Your app can now show Borat.

<Image Source="borat.gif" IsAnimationPlaying="true"></Image>

animation.gif

#Xamarin #SwipeView in a ListView

gestures-tap-swipe.pngOnce you’ve upgraded to at least Xamarin 4.4, you can use the new SwipeView to easily add Swiping. If you have an older app with ListViews that haven’t yet been upgraded to the CollectionView, you can still use SwipeViews. Here’s how to retrofit:

In your iOS project add this to the Finished Launching before the Forms Init()

public override bool FinishedLaunching(UIApplication appNSDictionary options)
{
 
	Forms.SetFlags("SwipeView_Experimental");
	global::Xamarin.Forms.Forms.Init();

In your Android MainActivity add:

protected override void OnCreate(Bundle bundle)
{
	Forms.SetFlags("SwipeView_Experimental");

Now, open your Cell.xaml ContentView used by your ListView and wrap the full ContentView.Content in a SwipeView:

	<ContentView.Content>
 
	<SwipeView android:SwipeView.SwipeTransitionMode="Drag"        
                    ios:SwipeView.SwipeTransitionMode="Drag">
		<SwipeView.LeftItems>
			<SwipeItems>
				<SwipeItem Text="Favorite"
					   IconImageSource="listviewcell_opportunity.png"
					   BackgroundColor="LightGreen"
					 />
				<SwipeItem Text="Delete"
					  IconImageSource="listviewcell_opportunity.png"
					  BackgroundColor="LightPink"
					  />
			</SwipeItems>
		</SwipeView.LeftItems>

Your content here then close it up:

	  </SwipeView> 
  </ContentView.Content>

Then you’ll be able to swipe!

2020-01-16 11_46_53-Window.png

#Angular in #VSCode: Programmatic Router Outlet targeting

Mozilla_Firefox.pngdownload.jpgI wanted to put a component into a named router outlet, but do it from another component based on some database/API value. Here’s how I was able to get it to work relatively easily:

My main component, Customers, has this route setup:

    const routes: Routes = [
      {
        path: "customers",
        component: CustomersComponent,
        children: [
          {
            path: "customerlist",
            component: CustomerListComponent,
            outlet: "detailsOutlet"
          }
        ]
      }
    ];

and this named router outlet template:

   router-outlet name="detailsOutlet"

In the CustomerComponent I can then load the CustomerList component into the outlet:

    const parentPath = "customers";
    const childPath = "customerlist";
    this.router.navigate(
      [parentPath, { outlets: { detailsOutlet: childPath } }],
      {
        skipLocationChange: true
      }
    );

I used 2 const values to show where the string values come from. You’ll notice that the paths there match the route paths above.

I didn’t want the URL to change or the history to get the outlet assignment, so I specified the skipLocationChange.

 

#Angular and Asp.Net 3 Core 3: Creating up to date documentation

imagesAfter you create a new Asp.Net Core 3 Angular project, you’ll want to add documentation. Keeping it up to date is always a chore, but with some new tools, that can be made much easier.

We’re going to go over CompoDoc, a free tool to create and update Angular Documentation.

2019-11-12 11_15_10-Window.png

The first step is to install it into your Asp.Net Core 3 Angular app. Open up the ClientApp folder in a Terminal and enter this:

npm install --save @compodoc/compodoc

Once done, go to your package.json file and add the compodoc script to the script’s node:

2019-11-12 11_19_34-PluralsiteAngularRouting - Microsoft Visual Studio.png

To generate the docs, just run this in the same terminal:

 npm run compodoc

It will generate a ClientApp/documentation folder. Open the resulting index.html to view your new shiny docs.

Re-run the compodoc script to update as needed.

2019-11-12 11_23_01-Window.png

 

 

#Angular and Asp.Net Core 3: Using a real-fake backend for prototyping and testing.

2019-11-11 12_59_09-Window.png

Real-Fake backend. Yah, I know, it sounds weird.

I’m in a situation where I want my Angular code to post to a real HTTP backend and return some values, but I don’t want to wait/create a real Asp.Net Core 3 backend to test or wire up selenium. I need a really fast turn around in a prototype. In this article that’s what we’ll do.

I’ll use Angular for this post, but React or Vue, etc would work just fine.

I’ll assume you have a little bit of an Angular background, but it’s not needed too much to get the idea.

In my component I have a form submit handler wired up and a data service stub as well:

export class UserSettingsFormComponent implements OnInit {

  constructor(private dataServiceDataService) {}

  onSubmit(form: NgForm) {
    this.dataService.postUserSettingsForm(this.userSettings).subscribe(
      result => console.log('success', result),
      error => console.log('error: ', error)
    );
  }

My data service just returns what is posted:

export class DataService {
  constructor(private httpHttpClient) { }

   postUserSettingsForm(userSettings: UserSettings): Observable<any> {
       return this.http.post('https://putsreq.com/qYVARlIpT0IiOUSAmp0a', userSettings);
  }
}  

What’s the funny-looking URL? Here’s the magic. Go to https://putsreq.com and tap the Create a PutsReq button.

2019-11-11 12_53_58-Window.png

Then in the screen that appears,  add this to the “Response Builder and press Update:

var parsedBody = JSON.parse(request.body);
parsedBody.id='MyIdIsBest';
response.body=parsedBody;

Now when we run our Angular form and post the value, PutsReq will execute our request and return what we indicated.

With this we can quickly edit and experiment with posting and modifying a response from our Angular app.

Here’s what the PutsReq page will show as Requests from your app come in:

2019-11-11 12_57_47-qYVARlIpT0IiOUSAmp0a.png