I have a requirement to perform routing based on a dynamically constructed string. Something like "city-homestay-id" where "city" and "id" are dynamically replaced. How would I make it work with react-router.
Ex:
www.xxx.com/atlanta-homestay-12345
Thanks
Simply use <Route path="/:cityId" component={YourComponent} /> for dynamic routing and access Id in YourComponent
const { match: { params } } = this.props;
console.log(params.cityId);
Related
I've a content type called continent. Which we the name suggests contains all the information about each continents. Strapi already created API endpoints for me like
continents/:id
But I want to search the continent by it's name since the general user won't be able to search by id
I've created the endpoint
continents/:continent_name
I've also created custom controller following documentation
const { sanitizeEntity } =
requiree('strapi-utils');
module.exports = {
async findOne(ctx) {
const { continent_name } = ctx.params;
const entity = await
strapi.services.continent.findOne({
continent_name
});
return sanitizeEntity(entity, { model:
continents });
And also exposed the API to public
But doesn't seem to anything
Just returns error
How am I supposed to do it
For your use case, you don't need to extend the model controller. You can just pass the continent name as a query param . For example, your url could be something like base_url/continent?continent_name=Asia.
For the code mentioned in the question, there is an issue, the model name should be strapi.models.continent and not continents. Also in the first line requiree('strapi-utils'), you have an extra e in the require. I am assuming that was just a typo.
I'm facing a silly issue of the default value not being rendered in the form.
In my app, when the user is logged in, a form will be auto-filled with some of the details as it will fetch the data from the stored user information passed to my component through props.
In that case, my already selected 'Gender' i.e. the default value is not getting displayed when the component is rendered.
At the same time, when I passing the same value as hard-coded, it works perfectly fine.
I'm receiving the 'defaultValue' in 'renderGenderDropDown' as 'Male'(same as I stored in myValue const).
But, myValue const works, defaultValue doesn't.
And yes, my component is used in multiple other components and works perfectly fine. It basically, renders '' from 'React'.
What do I need to fix this?
Code:
renderGender() {
const { options, data } = this.props;
const gender = get(data, 'gender');
const defaultValue = gender ? capitalize(gender) : gender;
const fieldName = 'gender';
return this.renderGenderDropDown(fieldName, defaultValue, prefixOptions);
}
renderGenderDropDown(fieldName, defaultValue, options) {
const { configuration, id, validations } = this.props;
const myValue = 'Male';
return <AppDropDown
label={getLabel(fieldName, configuration, validations, 'gender')}
options={dropdownOptions}
defaultValue={myValue}
//defaultValue={defaultValue}
key={fieldName}
className={fieldName}
disabled={false}
id={id}
onChange={this.onGenderChange(this[fieldName])}
/>
}
In Javascript, there isnt a native capitalize() . This is probably returning back undefined instead of a string. Try this to capitalize the first letter in the string.
gender.charAt(0).toUpperCase() + gender.substr(1)
I am creating an NodeJs + AngularJS Application. I have list of Hotels stored into database. I want to create dynamic route based on the hotel name and the load partial view based on property ID.
E.g In my database I have:
HotelID HotelName
1 example hotel
2 second example hotel
3 third example hotel
In app.js I want something like this
var hotelierApp = angular.module('hotelierApp', ['ngRoute', 'ngCookies', 'pascalprecht.translate', 'hotelierApp.services', 'hotelierApp.directives', 'hotelierApp.filters', 'hotelierApp.controller']);
hotelierApp.run(function ($rootScope) {
$rootScope.langId = 1;
})
hotelierApp.config(['$routeProvider', '$locationProvider', '$translateProvider',
function ($routeProvider, $locationProvider, $translateProvider) {
angular.forEach(hotels, function (hotel) {
$routeProvider.when(hotel.name.replace(" ","-"), { templateUrl: 'partials/property', controller: propertyCtrl });
});
angular.forEach(reviews, function (review) {
$routeProvider.when(review.title.replace(" ","-"), { templateUrl: 'partials/review', controller: reviewCtrl });
});
$locationProvider.html5Mode(true);
$translateProvider.useStaticFilesLoader({
prefix: 'data/locale-',
suffix: '.json'
});
$translateProvider.preferredLanguage('en');
$translateProvider.useLocalStorage();
}
]);
Here Hotels/reviews will be the list coming from database by making api calls and also I want to pass their corresponding Ids as route params to the controller.
I have many other section in my application for which i have to create routes from database.
Please help.
Regards,
- Manoj
There is no reason you need to do that.
i'm pretty sure your routes can be factored into something like
$routeProvider.when("/:id/:name", {
templateUrl: 'partials/property', controller: propertyCtrl })
then use $routeParams to get name of the hotel in your controller.As for template urls,your can pass a function instead of a string that will resolve the name of the template you need to use.
templateUrl:function(pathParms){...}
So no need to use angular.forEach.
While this is using another router: http://dotjem.github.io/angular-routing/ the same stuff is possible in tne core router.
Here is illustrated what #mpm is saying you can do: http://plnkr.co/edit/8XuJswpx0FucwMczWTHF?p=preview
In your case I think Option1 would be most appropriate, this is because you talk about a generated url pr. hotel, which makes me assume that there is a large similarity in layout for all hotels.
When that is the case, they may as well share template, where you can just populate the template with the hotel specific data.
Using Grails (or hibernate), I was wanting to know if there is a specific design pattern or method we should be using when implementing a SEARCH of our domain.
For example, on my website, I want to be able to filter(or search) by multiple properties in the domain.
EG: For I have a page which displays a list of HOTELS. When I submit a search form, or if a user clicks "filter by name='blah'", when I enter the controller I get the following:
Domain
String name
String location
Controller
if(params.name && params.reference) {
// Find name/reference
} else if(params.name) {
// Find name
} else if(params.reference) {
// Find reference
} else {
// Find all
}
As you can understand, if there are more properties in the domain to search/filter, the longer the controller gets.
Any help. Please note, I do not want to use the 'searchable' plugin, as this is too complex for my needs.
I would embed these in a named query in the Domain class itself. For example:
Class Hotel {
String name
String city
String country
boolean isNice
static namedQueries = {
customSearch { p ->
if (p?.name) eq('name', p.name)
if (p?.city) eq('name', p.city)
if (p?.country) eq('name', p.country)
if (p?.isNice != null) eq('isNice', p.isNice)
}
}
}
Then later in a controller somewhere ...
def results = Hotel.customSearch(params)
Of course this is a very simple example, but you can expand on it using the same named query or even adding others and chaining them together.
Looking at Str::slug for my frontend URL generation but just wondering how you guys go about implementing it with routes etc, for example, how would you guys go about changing http://www.example.com/courses/1 to http://www.example.com/courses/this-course
OK, I did it this way:
// I have a slug field in my courses table and a slug field in my categories table, along with a category_id field in my courses table.
// Route
Route::get('courses/{categorySlug}/{slug?}', function($categorySlug, $slug) {
$course = Course::leftJoin('categories', 'categories.id', 'courses.category_id')
->where('categories.slug', $categorySlug)
->where('courses.slug', $slug)
->firstOrFail();
return View::make('courses.show')->with('course', $course);
});
Works like a charm. It gets the $categorySlug and $slug variables then uses them to filter the Eloquent model Course to get the correct course object from the database.
EDIT: You can generate a URL in your view like:
http://www.example.com/courses/it-training/mcse
By doing something like:
{{ $course->title }}
A have a method in my Category like below that retrieves the parent category slug. This could be better achieved though using some sort of presenter class which would allow you to simply use $course->url but I haven't got around to doing this yet. I will update the answer when I do.
public function parentCategorySlug($parentId)
{
if ($parentId === '0')
{
return $this->slug;
}
return $this->where('id', $parentId)->first()->slug;
}
You can use the cvierbrock's Eloquent-Sluggable package.
As for me I created a helper function and used the following method taken from here.
public static function getSlug($title, $model) {
$slug = Str::slug($title);
$slugCount = count( $model->whereRaw("url REGEXP '^{$slug}(-[0-9]*)?$'")->get() );
return ($slugCount > 0) ? "{$slug}-{$slugCount}" : $slug;
}
You can create a related model Slug, and approach the course in your methods like so:
$course = Slug::where('slug', $slug) -> firstOrFail() -> course;
I have also implemented a similar URL mapping but I preferred to have both the ID and the slug in the requested URL, like this:
http://www.example.com/courses/1/my-laravel-course
This method allows me to get the requested course object from the ID given in the URL, rather than having to store the slugs in my DB table.
Route::post('courses/(:num)/(:any)', function ($courseid, $slug) {
$course = Course::where('id', '=', $courseid)->get();
return View::make('courses.show')->with('course', $course);
}
For Laravel 8:
Given my URL:
http://www.example.com/courses/this-course
My route:
Route::get('/courses/{course:slug}' , function(Course $course){
return view('showCourse' , [
'course' => $course
])
})